]> git.ipfire.org Git - ipfire-2.x.git/commitdiff
kernel: add backports 3.18.1-1.
authorArne Fitzenreiter <arne_f@ipfire.org>
Wed, 31 Dec 2014 07:48:56 +0000 (08:48 +0100)
committerArne Fitzenreiter <arne_f@ipfire.org>
Wed, 31 Dec 2014 07:48:56 +0000 (08:48 +0100)
lfs/backports [new file with mode: 0644]
make.sh
src/patches/backports-3.18.1-1-grsecurity.patch [new file with mode: 0644]
src/patches/backports-3.18.1-1-ipfire-build.patch [new file with mode: 0644]
src/patches/backports-3.18.1-1_add_libertas_uap.patch [new file with mode: 0644]

diff --git a/lfs/backports b/lfs/backports
new file mode 100644 (file)
index 0000000..c5aae66
--- /dev/null
@@ -0,0 +1,116 @@
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2007-2014  IPFire Team <info@ipfire.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 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+###############################################################################
+# Definitions
+###############################################################################
+
+include Config
+
+VERSUFIX   = ipfire$(KCFG)
+
+VER        = 3.18.1-1
+
+THISAPP    = backports-$(VER)
+DL_FILE    = $(THISAPP).tar.xz
+DL_FROM    = $(URL_IPFIRE)
+DIR_APP    = $(DIR_SRC)/$(THISAPP)
+TARGET     = $(DIR_INFO)/$(THISAPP)-kmod-$(KVER)-$(VERSUFIX)
+
+###############################################################################
+# Top-level Rules
+###############################################################################
+
+objects = $(DL_FILE)
+
+$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
+
+$(DL_FILE)_MD5 = 6cef5f2c800e12441d2cba9fa42b6a5b
+
+install : $(TARGET)
+
+check : $(patsubst %,$(DIR_CHK)/%,$(objects))
+
+download :$(patsubst %,$(DIR_DL)/%,$(objects))
+
+md5 : $(subst %,%_MD5,$(objects))
+
+dist: 
+       $(PAK)
+
+###############################################################################
+# Downloading, checking, md5sum
+###############################################################################
+
+$(patsubst %,$(DIR_CHK)/%,$(objects)) :
+       @$(CHECK)
+
+$(patsubst %,$(DIR_DL)/%,$(objects)) :
+       @$(LOAD)
+
+$(subst %,%_MD5,$(objects)) :
+       @$(MD5)
+
+###############################################################################
+# Installation Details
+###############################################################################
+
+$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
+       @$(PREBUILD)
+       @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar Jxf $(DIR_DL)/$(DL_FILE)
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/backports-3.18.1-1-ipfire-build.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/backports-3.18.1-1-grsecurity.patch
+
+       # DVB patches
+       cd $(DIR_APP) && patch -Np2 < $(DIR_SRC)/src/patches/v4l-dvb_fix_tua6034_pll.patch
+
+       # Wlan patches
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/compat-drivers-3.8.3-ath_ignore_eeprom_regdomain.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.14.22-iwlwifi-noibss_only_on_radar_chan.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.10.37-rt2800usb_add_dlink_dwa137_usbid.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/backports-3.18.1-1_add_libertas_uap.patch
+
+       # generate config
+       cd $(DIR_APP) && make KLIB=/lib/modules/$(KVER)-$(VERSUFIX)/ allmodconfig
+
+       # Disable some settings
+       cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_DEVELOPER_WARNINGS=y/# CPTCFG_CFG80211_DEVELOPER_WARNINGS is not set/g" .config
+       cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_CERTIFICATION_ONUS=y/# CPTCFG_CFG80211_CERTIFICATION_ONUS is not set/g" .config
+       cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_REG_CELLULAR_HINTS=y/# CPTCFG_CFG80211_REG_CELLULAR_HINTS is not set/g" .config
+       cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_REG_RELAX_NO_IR=y/# CPTCFG_CFG80211_REG_RELAX_NO_IR is not set/g" .config
+       cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_INTERNAL_REGDB=y/# CPTCFG_CFG80211_INTERNAL_REGDB is not set/g" .config
+       cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_DEFAULT_PS=y/# CPTCFG_CFG80211_DEFAULT_PS is not set/g" .config
+       cd $(DIR_APP) && sed -i -e "s/CPTCFG_NFC=m/# CPTCFG_NFC is not set/g" .config
+
+       # Disable some modules (build fail)
+       cd $(DIR_APP) && sed -i -e "s/CPTCFG_VIDEO_VIA_CAMERA=m/# CPTCFG_VIDEO_VIA_CAMERA is not set/g" .config
+
+       # Disable DEBUG
+       cd $(DIR_APP) && sed -i -e "s/.*DEBUG=y/# & is not set/g" .config
+       cd $(DIR_APP) && sed -i -e "s/.*DEBUGFS=y/# & is not set/g" .config
+       cd $(DIR_APP) && sed -i -e "s/=y is not set/ is not set/g" .config
+
+       cd $(DIR_APP) && make $(MAKETUNING) KLIB=/lib/modules/$(KVER)-$(VERSUFIX)/ install
+
+       # Remove vsp1 module (not mach to our platforms)
+       rm -rf /lib/modules/$(KVER)-$(VERSUFIX)/kernel/drivers/media/platform/vsp1
+
+       @rm -rf $(DIR_APP)
+       @$(POSTBUILD)
diff --git a/make.sh b/make.sh
index fa7fb55f3f2af695ea2769272d4d7c16e0f98085..18ac3dac2a2e30f868cdccba2a98699d4eb7c094 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -408,6 +408,7 @@ buildipfire() {
        i586)
                # x86-pae (Native and new XEN) kernel build
                ipfiremake linux                        KCFG="-pae"
+               ipfiremake backports                    KCFG="-pae"
                ipfiremake cryptodev                    KCFG="-pae"
                ipfiremake e1000e                       KCFG="-pae"
                ipfiremake igb                          KCFG="-pae"
@@ -416,6 +417,7 @@ buildipfire() {
 
                # x86 kernel build
                ipfiremake linux                        KCFG=""
+               ipfiremake backports                    KCFG=""
                ipfiremake cryptodev                    KCFG=""
                ipfiremake e1000e                       KCFG=""
                ipfiremake igb                          KCFG=""
@@ -426,11 +428,13 @@ buildipfire() {
        armv5tel)
                # arm-rpi (Raspberry Pi) kernel build
                ipfiremake linux                        KCFG="-rpi"
+               ipfiremake backports                    KCFG="-rpi"
                ipfiremake cryptodev                    KCFG="-rpi"
                ipfiremake linux-initrd                 KCFG="-rpi"
 
                # arm multi platform (Panda, Wandboard ...) kernel build
                ipfiremake linux                        KCFG="-multi"
+               ipfiremake backports                    KCFG="-multi"
                ipfiremake cryptodev                    KCFG="-multi"
                ipfiremake e1000e                       KCFG="-multi"
                ipfiremake igb                          KCFG="-multi"
@@ -439,6 +443,7 @@ buildipfire() {
 
                # arm-kirkwood (Dreamplug, ICY-Box ...) kernel build
                ipfiremake linux                        KCFG="-kirkwood"
+               ipfiremake backports                    KCFG="-kirkwood"
                ipfiremake cryptodev                    KCFG="-kirkwood"
                ipfiremake e1000e                       KCFG="-kirkwood"
                ipfiremake igb                          KCFG="-kirkwood"
diff --git a/src/patches/backports-3.18.1-1-grsecurity.patch b/src/patches/backports-3.18.1-1-grsecurity.patch
new file mode 100644 (file)
index 0000000..711f2e3
--- /dev/null
@@ -0,0 +1,3806 @@
+diff -Naur backports-3.18.1-1.org/drivers/bluetooth/btwilink.c backports-3.18.1-1/drivers/bluetooth/btwilink.c
+--- backports-3.18.1-1.org/drivers/bluetooth/btwilink.c        2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/drivers/bluetooth/btwilink.c    2014-12-28 14:10:09.480888533 +0100
+@@ -288,7 +288,7 @@
+ static int bt_ti_probe(struct platform_device *pdev)
+ {
+-      static struct ti_st *hst;
++      struct ti_st *hst;
+       struct hci_dev *hdev;
+       int err;
+diff -Naur backports-3.18.1-1.org/drivers/media/dvb-core/dvbdev.c backports-3.18.1-1/drivers/media/dvb-core/dvbdev.c
+--- backports-3.18.1-1.org/drivers/media/dvb-core/dvbdev.c     2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/dvb-core/dvbdev.c 2014-12-28 14:10:09.528888772 +0100
+@@ -185,7 +185,7 @@
+                       const struct dvb_device *template, void *priv, int type)
+ {
+       struct dvb_device *dvbdev;
+-      struct file_operations *dvbdevfops;
++      file_operations_no_const *dvbdevfops;
+       struct device *clsdev;
+       int minor;
+       int id;
+diff -Naur backports-3.18.1-1.org/drivers/media/dvb-frontends/af9033.h backports-3.18.1-1/drivers/media/dvb-frontends/af9033.h
+--- backports-3.18.1-1.org/drivers/media/dvb-frontends/af9033.h        2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/dvb-frontends/af9033.h    2014-12-28 14:10:09.528888772 +0100
+@@ -96,6 +96,6 @@
+       int (*pid_filter_ctrl)(struct dvb_frontend *fe, int onoff);
+       int (*pid_filter)(struct dvb_frontend *fe, int index, u16 pid,
+                         int onoff);
+-};
++} __no_const;
+ #endif /* AF9033_H */
+diff -Naur backports-3.18.1-1.org/drivers/media/dvb-frontends/dib3000.h backports-3.18.1-1/drivers/media/dvb-frontends/dib3000.h
+--- backports-3.18.1-1.org/drivers/media/dvb-frontends/dib3000.h       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/dvb-frontends/dib3000.h   2014-12-28 14:10:09.528888772 +0100
+@@ -39,7 +39,7 @@
+       int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff);
+       int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff);
+       int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
+-};
++} __no_const;
+ #if IS_ENABLED(CPTCFG_DVB_DIB3000MB)
+ extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
+diff -Naur backports-3.18.1-1.org/drivers/media/dvb-frontends/dib7000p.h backports-3.18.1-1/drivers/media/dvb-frontends/dib7000p.h
+--- backports-3.18.1-1.org/drivers/media/dvb-frontends/dib7000p.h      2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/dvb-frontends/dib7000p.h  2014-12-28 14:10:09.528888772 +0100
+@@ -64,7 +64,7 @@
+       int (*get_adc_power)(struct dvb_frontend *fe);
+       int (*slave_reset)(struct dvb_frontend *fe);
+       struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
+-};
++} __no_const;
+ #if IS_ENABLED(CPTCFG_DVB_DIB7000P)
+ void *dib7000p_attach(struct dib7000p_ops *ops);
+diff -Naur backports-3.18.1-1.org/drivers/media/dvb-frontends/dib8000.h backports-3.18.1-1/drivers/media/dvb-frontends/dib8000.h
+--- backports-3.18.1-1.org/drivers/media/dvb-frontends/dib8000.h       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/dvb-frontends/dib8000.h   2014-12-28 14:10:09.528888772 +0100
+@@ -61,7 +61,7 @@
+       int (*pid_filter_ctrl)(struct dvb_frontend *fe, u8 onoff);
+       int (*pid_filter)(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
+       struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
+-};
++} __no_const;
+ #if IS_ENABLED(CPTCFG_DVB_DIB8000)
+ void *dib8000_attach(struct dib8000_ops *ops);
+diff -Naur backports-3.18.1-1.org/drivers/media/pci/cx88/cx88-video.c backports-3.18.1-1/drivers/media/pci/cx88/cx88-video.c
+--- backports-3.18.1-1.org/drivers/media/pci/cx88/cx88-video.c 2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/pci/cx88/cx88-video.c     2014-12-28 14:10:09.528888772 +0100
+@@ -50,9 +50,9 @@
+ /* ------------------------------------------------------------------ */
+-static unsigned int video_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
+-static unsigned int vbi_nr[]   = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
+-static unsigned int radio_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
++static int video_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
++static int vbi_nr[]   = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
++static int radio_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
+ module_param_array(video_nr, int, NULL, 0444);
+ module_param_array(vbi_nr,   int, NULL, 0444);
+diff -Naur backports-3.18.1-1.org/drivers/media/pci/ivtv/ivtv-driver.c backports-3.18.1-1/drivers/media/pci/ivtv/ivtv-driver.c
+--- backports-3.18.1-1.org/drivers/media/pci/ivtv/ivtv-driver.c        2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/pci/ivtv/ivtv-driver.c    2014-12-28 14:10:09.528888772 +0100
+@@ -83,7 +83,7 @@
+ MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl);
+ /* ivtv instance counter */
+-static atomic_t ivtv_instance = ATOMIC_INIT(0);
++static atomic_unchecked_t ivtv_instance = ATOMIC_INIT(0);
+ /* Parameter declarations */
+ static int cardtype[IVTV_MAX_CARDS];
+diff -Naur backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-core.c backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-core.c
+--- backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-core.c  2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-core.c      2014-12-28 14:10:09.528888772 +0100
+@@ -424,7 +424,7 @@
+ static int solo_sysfs_init(struct solo_dev *solo_dev)
+ {
+-      struct bin_attribute *sdram_attr = &solo_dev->sdram_attr;
++      bin_attribute_no_const *sdram_attr = &solo_dev->sdram_attr;
+       struct device *dev = &solo_dev->dev;
+       const char *driver;
+       int i;
+diff -Naur backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-g723.c backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-g723.c
+--- backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-g723.c  2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-g723.c      2014-12-28 14:10:09.528888772 +0100
+@@ -351,7 +351,7 @@
+ int solo_g723_init(struct solo_dev *solo_dev)
+ {
+-      static struct snd_device_ops ops = { NULL };
++      static struct snd_device_ops ops = { };
+       struct snd_card *card;
+       struct snd_kcontrol_new kctl;
+       char name[32];
+diff -Naur backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10.h backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10.h
+--- backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10.h       2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10.h   2014-12-28 14:10:09.532888798 +0100
+@@ -219,7 +219,7 @@
+       /* P2M DMA Engine */
+       struct solo_p2m_dev     p2m_dev[SOLO_NR_P2M];
+-      atomic_t                p2m_count;
++      atomic_unchecked_t      p2m_count;
+       int                     p2m_jiffies;
+       unsigned int            p2m_timeouts;
+diff -Naur backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-p2m.c backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-p2m.c
+--- backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-p2m.c   2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-p2m.c       2014-12-28 14:10:09.532888798 +0100
+@@ -73,7 +73,7 @@
+       /* Get next ID. According to Softlogic, 6110 has problems on !=0 P2M */
+       if (solo_dev->type != SOLO_DEV_6110 && multi_p2m) {
+-              p2m_id = atomic_inc_return(&solo_dev->p2m_count) % SOLO_NR_P2M;
++              p2m_id = atomic_inc_return_unchecked(&solo_dev->p2m_count) % SOLO_NR_P2M;
+               if (p2m_id < 0)
+                       p2m_id = -p2m_id;
+       }
+diff -Naur backports-3.18.1-1.org/drivers/media/platform/omap/omap_vout.c backports-3.18.1-1/drivers/media/platform/omap/omap_vout.c
+--- backports-3.18.1-1.org/drivers/media/platform/omap/omap_vout.c     2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/platform/omap/omap_vout.c 2014-12-28 14:10:09.532888798 +0100
+@@ -63,7 +63,6 @@
+       OMAP_VIDEO2,
+ };
+-static struct videobuf_queue_ops video_vbq_ops;
+ /* Variables configurable through module params*/
+ static u32 video1_numbuffers = 3;
+ static u32 video2_numbuffers = 3;
+@@ -1012,6 +1011,12 @@
+ {
+       struct videobuf_queue *q;
+       struct omap_vout_device *vout = NULL;
++      static struct videobuf_queue_ops video_vbq_ops = {
++              .buf_setup = omap_vout_buffer_setup,
++              .buf_prepare = omap_vout_buffer_prepare,
++              .buf_release = omap_vout_buffer_release,
++              .buf_queue = omap_vout_buffer_queue,
++      };
+       vout = video_drvdata(file);
+       v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
+@@ -1029,10 +1034,6 @@
+       vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+       q = &vout->vbq;
+-      video_vbq_ops.buf_setup = omap_vout_buffer_setup;
+-      video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
+-      video_vbq_ops.buf_release = omap_vout_buffer_release;
+-      video_vbq_ops.buf_queue = omap_vout_buffer_queue;
+       spin_lock_init(&vout->vbq_lock);
+       videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
+diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_grp_layer.c backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_grp_layer.c
+--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_grp_layer.c     2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_grp_layer.c 2014-12-28 14:10:09.532888798 +0100
+@@ -235,7 +235,7 @@
+ {
+       struct mxr_layer *layer;
+       int ret;
+-      struct mxr_layer_ops ops = {
++      static struct mxr_layer_ops ops = {
+               .release = mxr_graph_layer_release,
+               .buffer_set = mxr_graph_buffer_set,
+               .stream_set = mxr_graph_stream_set,
+diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer.h backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer.h
+--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer.h       2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer.h   2014-12-28 14:10:09.532888798 +0100
+@@ -156,7 +156,7 @@
+       /** layer index (unique identifier) */
+       int idx;
+       /** callbacks for layer methods */
+-      struct mxr_layer_ops ops;
++      struct mxr_layer_ops *ops;
+       /** format array */
+       const struct mxr_format **fmt_array;
+       /** size of format array */
+diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_reg.c backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_reg.c
+--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_reg.c   2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_reg.c       2014-12-28 14:10:09.532888798 +0100
+@@ -276,7 +276,7 @@
+               layer->update_buf = next;
+       }
+-      layer->ops.buffer_set(layer, layer->update_buf);
++      layer->ops->buffer_set(layer, layer->update_buf);
+       if (done && done != layer->shadow_buf)
+               vb2_buffer_done(&done->vb, VB2_BUF_STATE_DONE);
+diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_video.c backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_video.c
+--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_video.c 2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_video.c     2014-12-28 14:10:09.532888798 +0100
+@@ -210,7 +210,7 @@
+       layer->geo.src.height = layer->geo.src.full_height;
+       mxr_geometry_dump(mdev, &layer->geo);
+-      layer->ops.fix_geometry(layer, MXR_GEOMETRY_SINK, 0);
++      layer->ops->fix_geometry(layer, MXR_GEOMETRY_SINK, 0);
+       mxr_geometry_dump(mdev, &layer->geo);
+ }
+@@ -228,7 +228,7 @@
+       layer->geo.dst.full_width = mbus_fmt.width;
+       layer->geo.dst.full_height = mbus_fmt.height;
+       layer->geo.dst.field = mbus_fmt.field;
+-      layer->ops.fix_geometry(layer, MXR_GEOMETRY_SINK, 0);
++      layer->ops->fix_geometry(layer, MXR_GEOMETRY_SINK, 0);
+       mxr_geometry_dump(mdev, &layer->geo);
+ }
+@@ -334,7 +334,7 @@
+       /* set source size to highest accepted value */
+       geo->src.full_width = max(geo->dst.full_width, pix->width);
+       geo->src.full_height = max(geo->dst.full_height, pix->height);
+-      layer->ops.fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0);
++      layer->ops->fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0);
+       mxr_geometry_dump(mdev, &layer->geo);
+       /* set cropping to total visible screen */
+       geo->src.width = pix->width;
+@@ -342,12 +342,12 @@
+       geo->src.x_offset = 0;
+       geo->src.y_offset = 0;
+       /* assure consistency of geometry */
+-      layer->ops.fix_geometry(layer, MXR_GEOMETRY_CROP, MXR_NO_OFFSET);
++      layer->ops->fix_geometry(layer, MXR_GEOMETRY_CROP, MXR_NO_OFFSET);
+       mxr_geometry_dump(mdev, &layer->geo);
+       /* set full size to lowest possible value */
+       geo->src.full_width = 0;
+       geo->src.full_height = 0;
+-      layer->ops.fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0);
++      layer->ops->fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0);
+       mxr_geometry_dump(mdev, &layer->geo);
+       /* returning results */
+@@ -474,7 +474,7 @@
+               target->width = s->r.width;
+               target->height = s->r.height;
+-              layer->ops.fix_geometry(layer, stage, s->flags);
++              layer->ops->fix_geometry(layer, stage, s->flags);
+               /* retrieve update selection rectangle */
+               res.left = target->x_offset;
+@@ -954,13 +954,13 @@
+       mxr_output_get(mdev);
+       mxr_layer_update_output(layer);
+-      layer->ops.format_set(layer);
++      layer->ops->format_set(layer);
+       /* enabling layer in hardware */
+       spin_lock_irqsave(&layer->enq_slock, flags);
+       layer->state = MXR_LAYER_STREAMING;
+       spin_unlock_irqrestore(&layer->enq_slock, flags);
+-      layer->ops.stream_set(layer, MXR_ENABLE);
++      layer->ops->stream_set(layer, MXR_ENABLE);
+       mxr_streamer_get(mdev);
+       return 0;
+@@ -1030,7 +1030,7 @@
+       spin_unlock_irqrestore(&layer->enq_slock, flags);
+       /* disabling layer in hardware */
+-      layer->ops.stream_set(layer, MXR_DISABLE);
++      layer->ops->stream_set(layer, MXR_DISABLE);
+       /* remove one streamer */
+       mxr_streamer_put(mdev);
+       /* allow changes in output configuration */
+@@ -1068,8 +1068,8 @@
+ void mxr_layer_release(struct mxr_layer *layer)
+ {
+-      if (layer->ops.release)
+-              layer->ops.release(layer);
++      if (layer->ops->release)
++              layer->ops->release(layer);
+ }
+ void mxr_base_layer_release(struct mxr_layer *layer)
+@@ -1095,7 +1095,7 @@
+       layer->mdev = mdev;
+       layer->idx = idx;
+-      layer->ops = *ops;
++      layer->ops = ops;
+       spin_lock_init(&layer->enq_slock);
+       INIT_LIST_HEAD(&layer->enq_list);
+diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_vp_layer.c backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_vp_layer.c
+--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_vp_layer.c      2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_vp_layer.c  2014-12-28 14:10:09.532888798 +0100
+@@ -206,7 +206,7 @@
+ {
+       struct mxr_layer *layer;
+       int ret;
+-      struct mxr_layer_ops ops = {
++      static struct mxr_layer_ops ops = {
+               .release = mxr_vp_layer_release,
+               .buffer_set = mxr_vp_buffer_set,
+               .stream_set = mxr_vp_stream_set,
+diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-cadet.c backports-3.18.1-1/drivers/media/radio/radio-cadet.c
+--- backports-3.18.1-1.org/drivers/media/radio/radio-cadet.c   2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/radio/radio-cadet.c       2014-12-28 14:10:09.532888798 +0100
+@@ -333,6 +333,8 @@
+       unsigned char readbuf[RDS_BUFFER];
+       int i = 0;
++      if (count > RDS_BUFFER)
++              return -EFAULT;
+       mutex_lock(&dev->lock);
+       if (dev->rdsstat == 0)
+               cadet_start_rds(dev);
+@@ -349,8 +351,9 @@
+               readbuf[i++] = dev->rdsbuf[dev->rdsout++];
+       mutex_unlock(&dev->lock);
+-      if (i && copy_to_user(data, readbuf, i))
+-              return -EFAULT;
++      if (i > sizeof(readbuf) || (i && copy_to_user(data, readbuf, i)))
++              i = -EFAULT;
++
+       return i;
+ }
+diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-maxiradio.c backports-3.18.1-1/drivers/media/radio/radio-maxiradio.c
+--- backports-3.18.1-1.org/drivers/media/radio/radio-maxiradio.c       2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/radio/radio-maxiradio.c   2014-12-28 14:10:09.532888798 +0100
+@@ -61,7 +61,7 @@
+ /* TEA5757 pin mappings */
+ static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16;
+-static atomic_t maxiradio_instance = ATOMIC_INIT(0);
++static atomic_unchecked_t maxiradio_instance = ATOMIC_INIT(0);
+ #define PCI_VENDOR_ID_GUILLEMOT 0x5046
+ #define PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO 0x1001
+diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-shark2.c backports-3.18.1-1/drivers/media/radio/radio-shark2.c
+--- backports-3.18.1-1.org/drivers/media/radio/radio-shark2.c  2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/radio/radio-shark2.c      2014-12-28 14:10:09.532888798 +0100
+@@ -74,7 +74,7 @@
+       u8 *transfer_buffer;
+ };
+-static atomic_t shark_instance = ATOMIC_INIT(0);
++static atomic_unchecked_t shark_instance = ATOMIC_INIT(0);
+ static int shark_write_reg(struct radio_tea5777 *tea, u64 reg)
+ {
+diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-shark.c backports-3.18.1-1/drivers/media/radio/radio-shark.c
+--- backports-3.18.1-1.org/drivers/media/radio/radio-shark.c   2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/radio/radio-shark.c       2014-12-28 14:10:09.532888798 +0100
+@@ -79,7 +79,7 @@
+       u32 last_val;
+ };
+-static atomic_t shark_instance = ATOMIC_INIT(0);
++static atomic_unchecked_t shark_instance = ATOMIC_INIT(0);
+ static void shark_write_val(struct snd_tea575x *tea, u32 val)
+ {
+diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-si476x.c backports-3.18.1-1/drivers/media/radio/radio-si476x.c
+--- backports-3.18.1-1.org/drivers/media/radio/radio-si476x.c  2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/drivers/media/radio/radio-si476x.c      2014-12-28 14:10:09.532888798 +0100
+@@ -1445,7 +1445,7 @@
+       struct si476x_radio *radio;
+       struct v4l2_ctrl *ctrl;
+-      static atomic_t instance = ATOMIC_INIT(0);
++      static atomic_unchecked_t instance = ATOMIC_INIT(0);
+       radio = devm_kzalloc(&pdev->dev, sizeof(*radio), GFP_KERNEL);
+       if (!radio)
+diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/cinergyT2-core.c backports-3.18.1-1/drivers/media/usb/dvb-usb/cinergyT2-core.c
+--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/cinergyT2-core.c  2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/cinergyT2-core.c      2014-12-28 14:10:09.532888798 +0100
+@@ -50,29 +50,73 @@
+ static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable)
+ {
+-      char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
+-      char result[64];
+-      return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result,
+-                              sizeof(result), 0);
++      char *buf;
++      char *result;
++      int retval;
++
++      buf = kmalloc(2, GFP_KERNEL);
++      if (buf == NULL)
++              return -ENOMEM;
++      result = kmalloc(64, GFP_KERNEL);
++      if (result == NULL) {
++              kfree(buf);
++              return -ENOMEM;
++      }
++
++      buf[0] = CINERGYT2_EP1_CONTROL_STREAM_TRANSFER;
++      buf[1] = enable ? 1 : 0;
++
++      retval = dvb_usb_generic_rw(adap->dev, buf, 2, result, 64, 0);
++
++      kfree(buf);
++      kfree(result);
++      return retval;
+ }
+ static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
+ {
+-      char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
+-      char state[3];
+-      return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0);
++      char *buf;
++      char *state;
++      int retval;
++
++      buf = kmalloc(2, GFP_KERNEL);
++      if (buf == NULL)
++              return -ENOMEM;
++      state = kmalloc(3, GFP_KERNEL);
++      if (state == NULL) {
++              kfree(buf);
++              return -ENOMEM;
++      }
++
++      buf[0] = CINERGYT2_EP1_SLEEP_MODE;
++      buf[1] = enable ? 1 : 0;
++
++      retval = dvb_usb_generic_rw(d, buf, 2, state, 3, 0);
++
++      kfree(buf);
++      kfree(state);
++      return retval;
+ }
+ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
+ {
+-      char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
+-      char state[3];
++      char *query;
++      char *state;
+       int ret;
++      query = kmalloc(1, GFP_KERNEL);
++      if (query == NULL)
++              return -ENOMEM;
++      state = kmalloc(3, GFP_KERNEL);
++      if (state == NULL) {
++              kfree(query);
++              return -ENOMEM;
++      }
++
++      query[0] = CINERGYT2_EP1_GET_FIRMWARE_VERSION;
+       adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev);
+-      ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state,
+-                              sizeof(state), 0);
++      ret = dvb_usb_generic_rw(adap->dev, query, 1, state, 3, 0);
+       if (ret < 0) {
+               deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep "
+                       "state info\n");
+@@ -80,7 +124,8 @@
+       /* Copy this pointer as we are gonna need it in the release phase */
+       cinergyt2_usb_device = adap->dev;
+-
++      kfree(query);
++      kfree(state);
+       return 0;
+ }
+@@ -141,12 +186,23 @@
+ static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+ {
+       struct cinergyt2_state *st = d->priv;
+-      u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS;
++      u8 *key, *cmd;
+       int i;
++      cmd = kmalloc(1, GFP_KERNEL);
++      if (cmd == NULL)
++              return -EINVAL;
++      key = kzalloc(5, GFP_KERNEL);
++      if (key == NULL) {
++              kfree(cmd);
++              return -EINVAL;
++      }
++
++      cmd[0] = CINERGYT2_EP1_GET_RC_EVENTS;
++
+       *state = REMOTE_NO_KEY_PRESSED;
+-      dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
++      dvb_usb_generic_rw(d, cmd, 1, key, 5, 0);
+       if (key[4] == 0xff) {
+               /* key repeat */
+               st->rc_counter++;
+@@ -157,12 +213,12 @@
+                                       *event = d->last_event;
+                                       deb_rc("repeat key, event %x\n",
+                                                  *event);
+-                                      return 0;
++                                      goto out;
+                               }
+                       }
+                       deb_rc("repeated key (non repeatable)\n");
+               }
+-              return 0;
++              goto out;
+       }
+       /* hack to pass checksum on the custom field */
+@@ -174,6 +230,9 @@
+               deb_rc("key: %*ph\n", 5, key);
+       }
++out:
++      kfree(cmd);
++      kfree(key);
+       return 0;
+ }
+diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/cinergyT2-fe.c backports-3.18.1-1/drivers/media/usb/dvb-usb/cinergyT2-fe.c
+--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/cinergyT2-fe.c    2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/cinergyT2-fe.c        2014-12-28 14:10:09.532888798 +0100
+@@ -145,103 +145,176 @@
+                                       fe_status_t *status)
+ {
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+-      struct dvbt_get_status_msg result;
+-      u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
++      struct dvbt_get_status_msg *result;
++      u8 *cmd;
+       int ret;
+-      ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
+-                      sizeof(result), 0);
++      cmd = kmalloc(1, GFP_KERNEL);
++      if (cmd == NULL)
++              return -ENOMEM;
++      result = kmalloc(sizeof(*result), GFP_KERNEL);
++      if (result == NULL) {
++              kfree(cmd);
++              return -ENOMEM;
++      }
++
++      cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS;
++
++      ret = dvb_usb_generic_rw(state->d, cmd, 1, (u8 *)result,
++                      sizeof(*result), 0);
+       if (ret < 0)
+-              return ret;
++              goto out;
+       *status = 0;
+-      if (0xffff - le16_to_cpu(result.gain) > 30)
++      if (0xffff - le16_to_cpu(result->gain) > 30)
+               *status |= FE_HAS_SIGNAL;
+-      if (result.lock_bits & (1 << 6))
++      if (result->lock_bits & (1 << 6))
+               *status |= FE_HAS_LOCK;
+-      if (result.lock_bits & (1 << 5))
++      if (result->lock_bits & (1 << 5))
+               *status |= FE_HAS_SYNC;
+-      if (result.lock_bits & (1 << 4))
++      if (result->lock_bits & (1 << 4))
+               *status |= FE_HAS_CARRIER;
+-      if (result.lock_bits & (1 << 1))
++      if (result->lock_bits & (1 << 1))
+               *status |= FE_HAS_VITERBI;
+       if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
+                       (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
+               *status &= ~FE_HAS_LOCK;
+-      return 0;
++out:
++      kfree(cmd);
++      kfree(result);
++      return ret;
+ }
+ static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
+ {
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+-      struct dvbt_get_status_msg status;
+-      char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
++      struct dvbt_get_status_msg *status;
++      char *cmd;
+       int ret;
+-      ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
+-                              sizeof(status), 0);
++      cmd = kmalloc(1, GFP_KERNEL);
++      if (cmd == NULL)
++              return -ENOMEM;
++      status = kmalloc(sizeof(*status), GFP_KERNEL);
++      if (status == NULL) {
++              kfree(cmd);
++              return -ENOMEM;
++      }
++
++      cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS;
++
++      ret = dvb_usb_generic_rw(state->d, cmd, 1, (char *)status,
++                              sizeof(*status), 0);
+       if (ret < 0)
+-              return ret;
++              goto out;
+-      *ber = le32_to_cpu(status.viterbi_error_rate);
++      *ber = le32_to_cpu(status->viterbi_error_rate);
++out:
++      kfree(cmd);
++      kfree(status);
+       return 0;
+ }
+ static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
+ {
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+-      struct dvbt_get_status_msg status;
+-      u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
++      struct dvbt_get_status_msg *status;
++      u8 *cmd;
+       int ret;
+-      ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
+-                              sizeof(status), 0);
++      cmd = kmalloc(1, GFP_KERNEL);
++      if (cmd == NULL)
++              return -ENOMEM;
++      status = kmalloc(sizeof(*status), GFP_KERNEL);
++      if (status == NULL) {
++              kfree(cmd);
++              return -ENOMEM;
++      }
++
++      cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS;
++
++      ret = dvb_usb_generic_rw(state->d, cmd, 1, (u8 *)status,
++                              sizeof(*status), 0);
+       if (ret < 0) {
+               err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
+                       ret);
+-              return ret;
++              goto out;
+       }
+-      *unc = le32_to_cpu(status.uncorrected_block_count);
+-      return 0;
++      *unc = le32_to_cpu(status->uncorrected_block_count);
++
++out:
++      kfree(cmd);
++      kfree(status);
++      return ret;
+ }
+ static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
+                                               u16 *strength)
+ {
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+-      struct dvbt_get_status_msg status;
+-      char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
++      struct dvbt_get_status_msg *status;
++      char *cmd;
+       int ret;
+-      ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
+-                              sizeof(status), 0);
++      cmd = kmalloc(1, GFP_KERNEL);
++      if (cmd == NULL)
++              return -ENOMEM;
++      status = kmalloc(sizeof(*status), GFP_KERNEL);
++      if (status == NULL) {
++              kfree(cmd);
++              return -ENOMEM;
++      }
++
++      cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS;
++
++      ret = dvb_usb_generic_rw(state->d, cmd, 1, (char *)status,
++                              sizeof(*status), 0);
+       if (ret < 0) {
+               err("cinergyt2_fe_read_signal_strength() Failed!"
+                       " (Error=%d)\n", ret);
+-              return ret;
++              goto out;
+       }
+-      *strength = (0xffff - le16_to_cpu(status.gain));
++      *strength = (0xffff - le16_to_cpu(status->gain));
++
++out:
++      kfree(cmd);
++      kfree(status);
+       return 0;
+ }
+ static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
+ {
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+-      struct dvbt_get_status_msg status;
+-      char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
++      struct dvbt_get_status_msg *status;
++      char *cmd;
+       int ret;
+-      ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
+-                              sizeof(status), 0);
++      cmd = kmalloc(1, GFP_KERNEL);
++      if (cmd == NULL)
++              return -ENOMEM;
++      status = kmalloc(sizeof(*status), GFP_KERNEL);
++      if (status == NULL) {
++              kfree(cmd);
++              return -ENOMEM;
++      }
++
++      cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS;
++
++      ret = dvb_usb_generic_rw(state->d, cmd, 1, (char *)status,
++                              sizeof(*status), 0);
+       if (ret < 0) {
+               err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
+-              return ret;
++              goto out;
+       }
+-      *snr = (status.snr << 8) | status.snr;
+-      return 0;
++      *snr = (status->snr << 8) | status->snr;
++
++out:
++      kfree(cmd);
++      kfree(status);
++      return ret;
+ }
+ static int cinergyt2_fe_init(struct dvb_frontend *fe)
+@@ -266,35 +339,46 @@
+ {
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct cinergyt2_fe_state *state = fe->demodulator_priv;
+-      struct dvbt_set_parameters_msg param;
+-      char result[2];
++      struct dvbt_set_parameters_msg *param;
++      char *result;
+       int err;
+-      param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
+-      param.tps = cpu_to_le16(compute_tps(fep));
+-      param.freq = cpu_to_le32(fep->frequency / 1000);
+-      param.flags = 0;
++      result = kmalloc(2, GFP_KERNEL);
++      if (result == NULL)
++              return -ENOMEM;
++      param = kmalloc(sizeof(*param), GFP_KERNEL);
++      if (param == NULL) {
++              kfree(result);
++              return -ENOMEM;
++      }
++
++      param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
++      param->tps = cpu_to_le16(compute_tps(fep));
++      param->freq = cpu_to_le32(fep->frequency / 1000);
++      param->flags = 0;
+       switch (fep->bandwidth_hz) {
+       default:
+       case 8000000:
+-              param.bandwidth = 8;
++              param->bandwidth = 8;
+               break;
+       case 7000000:
+-              param.bandwidth = 7;
++              param->bandwidth = 7;
+               break;
+       case 6000000:
+-              param.bandwidth = 6;
++              param->bandwidth = 6;
+               break;
+       }
+       err = dvb_usb_generic_rw(state->d,
+-                      (char *)&param, sizeof(param),
+-                      result, sizeof(result), 0);
++                      (char *)param, sizeof(*param),
++                      result, 2, 0);
+       if (err < 0)
+               err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);
+-      return (err < 0) ? err : 0;
++      kfree(result);
++      kfree(param);
++      return err;
+ }
+ static void cinergyt2_fe_release(struct dvb_frontend *fe)
+diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/dvb-usb-firmware.c backports-3.18.1-1/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/dvb-usb-firmware.c        2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/dvb-usb-firmware.c    2014-12-28 14:10:09.532888798 +0100
+@@ -35,42 +35,57 @@
+ int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
+ {
+-      struct hexline hx;
+-      u8 reset;
++      struct hexline *hx;
++      u8 *reset;
+       int ret,pos=0;
++      reset = kmalloc(1, GFP_KERNEL);
++      if (reset == NULL)
++              return -ENOMEM;
++
++      hx = kmalloc(sizeof(struct hexline), GFP_KERNEL);
++      if (hx == NULL) {
++              kfree(reset);
++              return -ENOMEM;
++      }
++
+       /* stop the CPU */
+-      reset = 1;
+-      if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
++      reset[0] = 1;
++      if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,reset,1)) != 1)
+               err("could not stop the USB controller CPU.");
+-      while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
+-              deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
+-              ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
++      while ((ret = dvb_usb_get_hexline(fw,hx,&pos)) > 0) {
++              deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx->addr,hx->len,hx->chk);
++              ret = usb_cypress_writemem(udev,hx->addr,hx->data,hx->len);
+-              if (ret != hx.len) {
++              if (ret != hx->len) {
+                       err("error while transferring firmware "
+                               "(transferred size: %d, block size: %d)",
+-                              ret,hx.len);
++                              ret,hx->len);
+                       ret = -EINVAL;
+                       break;
+               }
+       }
+       if (ret < 0) {
+               err("firmware download failed at %d with %d",pos,ret);
++              kfree(reset);
++              kfree(hx);
+               return ret;
+       }
+       if (ret == 0) {
+               /* restart the CPU */
+-              reset = 0;
+-              if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
++              reset[0] = 0;
++              if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,reset,1) != 1) {
+                       err("could not restart the USB controller CPU.");
+                       ret = -EINVAL;
+               }
+       } else
+               ret = -EIO;
++      kfree(reset);
++      kfree(hx);
++
+       return ret;
+ }
+ EXPORT_SYMBOL(usb_cypress_load_firmware);
+diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/dw2102.c backports-3.18.1-1/drivers/media/usb/dvb-usb/dw2102.c
+--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/dw2102.c  2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/dw2102.c      2014-12-28 14:10:09.536888811 +0100
+@@ -118,7 +118,7 @@
+ struct s6x0_state {
+       int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
+-};
++} __no_const;
+ /* debug */
+ static int dvb_usb_dw2102_debug;
+diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/technisat-usb2.c backports-3.18.1-1/drivers/media/usb/dvb-usb/technisat-usb2.c
+--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/technisat-usb2.c  2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/technisat-usb2.c      2014-12-28 14:10:09.536888811 +0100
+@@ -87,8 +87,11 @@
+ static int technisat_usb2_i2c_access(struct usb_device *udev,
+               u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
+ {
+-      u8 b[64];
+-      int ret, actual_length;
++      u8 *b = kmalloc(64, GFP_KERNEL);
++      int ret, actual_length, error = 0;
++
++      if (b == NULL)
++              return -ENOMEM;
+       deb_i2c("i2c-access: %02x, tx: ", device_addr);
+       debug_dump(tx, txlen, deb_i2c);
+@@ -121,7 +124,8 @@
+       if (ret < 0) {
+               err("i2c-error: out failed %02x = %d", device_addr, ret);
+-              return -ENODEV;
++              error = -ENODEV;
++              goto out;
+       }
+       ret = usb_bulk_msg(udev,
+@@ -129,7 +133,8 @@
+                       b, 64, &actual_length, 1000);
+       if (ret < 0) {
+               err("i2c-error: in failed %02x = %d", device_addr, ret);
+-              return -ENODEV;
++              error = -ENODEV;
++              goto out;
+       }
+       if (b[0] != I2C_STATUS_OK) {
+@@ -137,8 +142,10 @@
+               /* handle tuner-i2c-nak */
+               if (!(b[0] == I2C_STATUS_NAK &&
+                               device_addr == 0x60
+-                              /* && device_is_technisat_usb2 */))
+-                      return -ENODEV;
++                              /* && device_is_technisat_usb2 */)) {
++                      error = -ENODEV;
++                      goto out;
++              }
+       }
+       deb_i2c("status: %d, ", b[0]);
+@@ -152,7 +159,9 @@
+       deb_i2c("\n");
+-      return 0;
++out:
++      kfree(b);
++      return error;
+ }
+ static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+@@ -224,14 +233,16 @@
+ {
+       int ret;
+-      u8 led[8] = {
+-              red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
+-              0
+-      };
++      u8 *led = kzalloc(8, GFP_KERNEL);
++
++      if (led == NULL)
++              return -ENOMEM;
+       if (disable_led_control && state != TECH_LED_OFF)
+               return 0;
++      led[0] = red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST;
++
+       switch (state) {
+       case TECH_LED_ON:
+               led[1] = 0x82;
+@@ -263,16 +274,22 @@
+               red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
+               USB_TYPE_VENDOR | USB_DIR_OUT,
+               0, 0,
+-              led, sizeof(led), 500);
++              led, 8, 500);
+       mutex_unlock(&d->i2c_mutex);
++
++      kfree(led);
++
+       return ret;
+ }
+ static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green)
+ {
+       int ret;
+-      u8 b = 0;
++      u8 *b = kzalloc(1, GFP_KERNEL);
++
++      if (b == NULL)
++              return -ENOMEM;
+       if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+               return -EAGAIN;
+@@ -281,10 +298,12 @@
+               SET_LED_TIMER_DIVIDER_VENDOR_REQUEST,
+               USB_TYPE_VENDOR | USB_DIR_OUT,
+               (red << 8) | green, 0,
+-              &b, 1, 500);
++              b, 1, 500);
+       mutex_unlock(&d->i2c_mutex);
++      kfree(b);
++
+       return ret;
+ }
+@@ -328,7 +347,7 @@
+               struct dvb_usb_device_description **desc, int *cold)
+ {
+       int ret;
+-      u8 version[3];
++      u8 *version = kmalloc(3, GFP_KERNEL);
+       /* first select the interface */
+       if (usb_set_interface(udev, 0, 1) != 0)
+@@ -338,11 +357,14 @@
+       *cold = 0; /* by default do not download a firmware - just in case something is wrong */
++      if (version == NULL)
++              return 0;
++
+       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+               GET_VERSION_INFO_VENDOR_REQUEST,
+               USB_TYPE_VENDOR | USB_DIR_IN,
+               0, 0,
+-              version, sizeof(version), 500);
++              version, 3, 500);
+       if (ret < 0)
+               *cold = 1;
+@@ -351,6 +373,8 @@
+               *cold = 0;
+       }
++      kfree(version);
++
+       return 0;
+ }
+@@ -591,10 +615,15 @@
+ static int technisat_usb2_get_ir(struct dvb_usb_device *d)
+ {
+-      u8 buf[62], *b;
++      u8 *buf, *b;
+       int ret;
+       struct ir_raw_event ev;
++      buf = kmalloc(62, GFP_KERNEL);
++
++      if (buf == NULL)
++              return -ENOMEM;
++
+       buf[0] = GET_IR_DATA_VENDOR_REQUEST;
+       buf[1] = 0x08;
+       buf[2] = 0x8f;
+@@ -617,16 +646,20 @@
+                       GET_IR_DATA_VENDOR_REQUEST,
+                       USB_TYPE_VENDOR | USB_DIR_IN,
+                       0x8080, 0,
+-                      buf, sizeof(buf), 500);
++                      buf, 62, 500);
+ unlock:
+       mutex_unlock(&d->i2c_mutex);
+-      if (ret < 0)
++      if (ret < 0) {
++              kfree(buf);
+               return ret;
++      }
+-      if (ret == 1)
++      if (ret == 1) {
++              kfree(buf);
+               return 0; /* no key pressed */
++      }
+       /* decoding */
+       b = buf+1;
+@@ -653,6 +686,8 @@
+       ir_raw_event_handle(d->rc_dev);
++      kfree(buf);
++
+       return 1;
+ }
+diff -Naur backports-3.18.1-1.org/drivers/media/v4l2-core/v4l2-device.c backports-3.18.1-1/drivers/media/v4l2-core/v4l2-device.c
+--- backports-3.18.1-1.org/drivers/media/v4l2-core/v4l2-device.c       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/v4l2-core/v4l2-device.c   2014-12-28 14:10:09.536888811 +0100
+@@ -75,9 +75,9 @@
+ EXPORT_SYMBOL_GPL(v4l2_device_put);
+ int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
+-                                              atomic_t *instance)
++                                              atomic_unchecked_t *instance)
+ {
+-      int num = atomic_inc_return(instance) - 1;
++      int num = atomic_inc_return_unchecked(instance) - 1;
+       int len = strlen(basename);
+       if (basename[len - 1] >= '0' && basename[len - 1] <= '9')
+diff -Naur backports-3.18.1-1.org/drivers/media/v4l2-core/v4l2-ioctl.c backports-3.18.1-1/drivers/media/v4l2-core/v4l2-ioctl.c
+--- backports-3.18.1-1.org/drivers/media/v4l2-core/v4l2-ioctl.c        2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/media/v4l2-core/v4l2-ioctl.c    2014-12-28 14:10:09.536888811 +0100
+@@ -2142,7 +2142,8 @@
+                               struct file *file, void *fh, void *p);
+       } u;
+       void (*debug)(const void *arg, bool write_only);
+-};
++} __do_const;
++typedef struct v4l2_ioctl_info __no_const v4l2_ioctl_info_no_const;
+ /* This control needs a priority check */
+ #define INFO_FL_PRIO  (1 << 0)
+@@ -2326,7 +2327,7 @@
+       struct video_device *vfd = video_devdata(file);
+       const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
+       bool write_only = false;
+-      struct v4l2_ioctl_info default_info;
++      v4l2_ioctl_info_no_const default_info;
+       const struct v4l2_ioctl_info *info;
+       void *fh = file->private_data;
+       struct v4l2_fh *vfh = NULL;
+@@ -2413,7 +2414,7 @@
+                               ret = -EINVAL;
+                               break;
+                       }
+-                      *user_ptr = (void __user *)buf->m.planes;
++                      *user_ptr = (void __force_user *)buf->m.planes;
+                       *kernel_ptr = (void **)&buf->m.planes;
+                       *array_size = sizeof(struct v4l2_plane) * buf->length;
+                       ret = 1;
+@@ -2430,7 +2431,7 @@
+                               ret = -EINVAL;
+                               break;
+                       }
+-                      *user_ptr = (void __user *)edid->edid;
++                      *user_ptr = (void __force_user *)edid->edid;
+                       *kernel_ptr = (void **)&edid->edid;
+                       *array_size = edid->blocks * 128;
+                       ret = 1;
+@@ -2448,7 +2449,7 @@
+                               ret = -EINVAL;
+                               break;
+                       }
+-                      *user_ptr = (void __user *)ctrls->controls;
++                      *user_ptr = (void __force_user *)ctrls->controls;
+                       *kernel_ptr = (void **)&ctrls->controls;
+                       *array_size = sizeof(struct v4l2_ext_control)
+                                   * ctrls->count;
+@@ -2549,7 +2550,7 @@
+       }
+       if (has_array_args) {
+-              *kernel_ptr = (void __force *)user_ptr;
++              *kernel_ptr = (void __force_kernel *)user_ptr;
+               if (copy_to_user(user_ptr, mbuf, array_size))
+                       err = -EFAULT;
+               goto out_array_args;
+diff -Naur backports-3.18.1-1.org/drivers/net/ieee802154/fakehard.c backports-3.18.1-1/drivers/net/ieee802154/fakehard.c
+--- backports-3.18.1-1.org/drivers/net/ieee802154/fakehard.c   2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/ieee802154/fakehard.c       2014-12-28 14:10:09.556888909 +0100
+@@ -365,7 +365,7 @@
+       phy->transmit_power = 0xbf;
+       dev->netdev_ops = &fake_ops;
+-      dev->ml_priv = &fake_mlme;
++      dev->ml_priv = (void *)&fake_mlme;
+       priv = netdev_priv(dev);
+       priv->phy = phy;
+diff -Naur backports-3.18.1-1.org/drivers/net/usb/sierra_net.c backports-3.18.1-1/drivers/net/usb/sierra_net.c
+--- backports-3.18.1-1.org/drivers/net/usb/sierra_net.c        2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/usb/sierra_net.c    2014-12-28 14:10:09.560888936 +0100
+@@ -51,7 +51,7 @@
+ /* atomic counter partially included in MAC address to make sure 2 devices
+  * do not end up with the same MAC - concept breaks in case of > 255 ifaces
+  */
+-static        atomic_t iface_counter = ATOMIC_INIT(0);
++static        atomic_unchecked_t iface_counter = ATOMIC_INIT(0);
+ /*
+  * SYNC Timer Delay definition used to set the expiry time
+@@ -697,7 +697,7 @@
+       dev->net->netdev_ops = &sierra_net_device_ops;
+       /* change MAC addr to include, ifacenum, and to be unique */
+-      dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
++      dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return_unchecked(&iface_counter);
+       dev->net->dev_addr[ETH_ALEN-1] = ifacenum;
+       /* we will have to manufacture ethernet headers, prepare template */
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/at76c50x-usb.c backports-3.18.1-1/drivers/net/wireless/at76c50x-usb.c
+--- backports-3.18.1-1.org/drivers/net/wireless/at76c50x-usb.c 2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/at76c50x-usb.c     2014-12-28 14:10:09.560888936 +0100
+@@ -353,7 +353,7 @@
+ }
+ /* Convert timeout from the DFU status to jiffies */
+-static inline unsigned long at76_get_timeout(struct dfu_status *s)
++static inline unsigned long __intentional_overflow(-1) at76_get_timeout(struct dfu_status *s)
+ {
+       return msecs_to_jiffies((s->poll_timeout[2] << 16)
+                               | (s->poll_timeout[1] << 8)
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath10k/htc.c backports-3.18.1-1/drivers/net/wireless/ath/ath10k/htc.c
+--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath10k/htc.c       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/ath/ath10k/htc.c   2014-12-28 14:10:09.560888936 +0100
+@@ -848,7 +848,10 @@
+ /* registered target arrival callback from the HIF layer */
+ int ath10k_htc_init(struct ath10k *ar)
+ {
+-      struct ath10k_hif_cb htc_callbacks;
++      static struct ath10k_hif_cb htc_callbacks = {
++              .rx_completion = ath10k_htc_rx_completion_handler,
++              .tx_completion = ath10k_htc_tx_completion_handler,
++      };
+       struct ath10k_htc_ep *ep = NULL;
+       struct ath10k_htc *htc = &ar->htc;
+@@ -857,8 +860,6 @@
+       ath10k_htc_reset_endpoint_states(htc);
+       /* setup HIF layer callbacks */
+-      htc_callbacks.rx_completion = ath10k_htc_rx_completion_handler;
+-      htc_callbacks.tx_completion = ath10k_htc_tx_completion_handler;
+       htc->ar = ar;
+       /* Get HIF default pipe for HTC message exchange */
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath10k/htc.h backports-3.18.1-1/drivers/net/wireless/ath/ath10k/htc.h
+--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath10k/htc.h       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/ath/ath10k/htc.h   2014-12-28 14:10:09.560888936 +0100
+@@ -270,13 +270,13 @@
+ struct ath10k_htc_ops {
+       void (*target_send_suspend_complete)(struct ath10k *ar);
+-};
++} __no_const;
+ struct ath10k_htc_ep_ops {
+       void (*ep_tx_complete)(struct ath10k *, struct sk_buff *);
+       void (*ep_rx_complete)(struct ath10k *, struct sk_buff *);
+       void (*ep_tx_credits)(struct ath10k *);
+-};
++} __no_const;
+ /* service connection information */
+ struct ath10k_htc_svc_conn_req {
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/ar9002_mac.c backports-3.18.1-1/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/ar9002_mac.c 2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/ath/ath9k/ar9002_mac.c     2014-12-28 14:10:09.560888936 +0100
+@@ -220,8 +220,8 @@
+       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+-      ACCESS_ONCE(ads->ds_link) = i->link;
+-      ACCESS_ONCE(ads->ds_data) = i->buf_addr[0];
++      ACCESS_ONCE_RW(ads->ds_link) = i->link;
++      ACCESS_ONCE_RW(ads->ds_data) = i->buf_addr[0];
+       ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore);
+       ctl6 = SM(i->keytype, AR_EncrType);
+@@ -235,26 +235,26 @@
+       if ((i->is_first || i->is_last) &&
+           i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) {
+-              ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0)
++              ACCESS_ONCE_RW(ads->ds_ctl2) = set11nTries(i->rates, 0)
+                       | set11nTries(i->rates, 1)
+                       | set11nTries(i->rates, 2)
+                       | set11nTries(i->rates, 3)
+                       | (i->dur_update ? AR_DurUpdateEna : 0)
+                       | SM(0, AR_BurstDur);
+-              ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0)
++              ACCESS_ONCE_RW(ads->ds_ctl3) = set11nRate(i->rates, 0)
+                       | set11nRate(i->rates, 1)
+                       | set11nRate(i->rates, 2)
+                       | set11nRate(i->rates, 3);
+       } else {
+-              ACCESS_ONCE(ads->ds_ctl2) = 0;
+-              ACCESS_ONCE(ads->ds_ctl3) = 0;
++              ACCESS_ONCE_RW(ads->ds_ctl2) = 0;
++              ACCESS_ONCE_RW(ads->ds_ctl3) = 0;
+       }
+       if (!i->is_first) {
+-              ACCESS_ONCE(ads->ds_ctl0) = 0;
+-              ACCESS_ONCE(ads->ds_ctl1) = ctl1;
+-              ACCESS_ONCE(ads->ds_ctl6) = ctl6;
++              ACCESS_ONCE_RW(ads->ds_ctl0) = 0;
++              ACCESS_ONCE_RW(ads->ds_ctl1) = ctl1;
++              ACCESS_ONCE_RW(ads->ds_ctl6) = ctl6;
+               return;
+       }
+@@ -279,7 +279,7 @@
+               break;
+       }
+-      ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
++      ACCESS_ONCE_RW(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
+               | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
+               | SM(i->txpower, AR_XmitPower0)
+               | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
+@@ -289,27 +289,27 @@
+               | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
+                  (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
+-      ACCESS_ONCE(ads->ds_ctl1) = ctl1;
+-      ACCESS_ONCE(ads->ds_ctl6) = ctl6;
++      ACCESS_ONCE_RW(ads->ds_ctl1) = ctl1;
++      ACCESS_ONCE_RW(ads->ds_ctl6) = ctl6;
+       if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST)
+               return;
+-      ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0)
++      ACCESS_ONCE_RW(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0)
+               | set11nPktDurRTSCTS(i->rates, 1);
+-      ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2)
++      ACCESS_ONCE_RW(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2)
+               | set11nPktDurRTSCTS(i->rates, 3);
+-      ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0)
++      ACCESS_ONCE_RW(ads->ds_ctl7) = set11nRateFlags(i->rates, 0)
+               | set11nRateFlags(i->rates, 1)
+               | set11nRateFlags(i->rates, 2)
+               | set11nRateFlags(i->rates, 3)
+               | SM(i->rtscts_rate, AR_RTSCTSRate);
+-      ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower, AR_XmitPower1);
+-      ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower, AR_XmitPower2);
+-      ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower, AR_XmitPower3);
++      ACCESS_ONCE_RW(ads->ds_ctl9) = SM(i->txpower, AR_XmitPower1);
++      ACCESS_ONCE_RW(ads->ds_ctl10) = SM(i->txpower, AR_XmitPower2);
++      ACCESS_ONCE_RW(ads->ds_ctl11) = SM(i->txpower, AR_XmitPower3);
+ }
+ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/ar9003_mac.c backports-3.18.1-1/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/ar9003_mac.c 2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/ath/ath9k/ar9003_mac.c     2014-12-28 14:10:09.560888936 +0100
+@@ -39,47 +39,47 @@
+             (i->qcu << AR_TxQcuNum_S) | desc_len;
+       checksum += val;
+-      ACCESS_ONCE(ads->info) = val;
++      ACCESS_ONCE_RW(ads->info) = val;
+       checksum += i->link;
+-      ACCESS_ONCE(ads->link) = i->link;
++      ACCESS_ONCE_RW(ads->link) = i->link;
+       checksum += i->buf_addr[0];
+-      ACCESS_ONCE(ads->data0) = i->buf_addr[0];
++      ACCESS_ONCE_RW(ads->data0) = i->buf_addr[0];
+       checksum += i->buf_addr[1];
+-      ACCESS_ONCE(ads->data1) = i->buf_addr[1];
++      ACCESS_ONCE_RW(ads->data1) = i->buf_addr[1];
+       checksum += i->buf_addr[2];
+-      ACCESS_ONCE(ads->data2) = i->buf_addr[2];
++      ACCESS_ONCE_RW(ads->data2) = i->buf_addr[2];
+       checksum += i->buf_addr[3];
+-      ACCESS_ONCE(ads->data3) = i->buf_addr[3];
++      ACCESS_ONCE_RW(ads->data3) = i->buf_addr[3];
+       checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen);
+-      ACCESS_ONCE(ads->ctl3) = val;
++      ACCESS_ONCE_RW(ads->ctl3) = val;
+       checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen);
+-      ACCESS_ONCE(ads->ctl5) = val;
++      ACCESS_ONCE_RW(ads->ctl5) = val;
+       checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen);
+-      ACCESS_ONCE(ads->ctl7) = val;
++      ACCESS_ONCE_RW(ads->ctl7) = val;
+       checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
+-      ACCESS_ONCE(ads->ctl9) = val;
++      ACCESS_ONCE_RW(ads->ctl9) = val;
+       checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff);
+-      ACCESS_ONCE(ads->ctl10) = checksum;
++      ACCESS_ONCE_RW(ads->ctl10) = checksum;
+       if (i->is_first || i->is_last) {
+-              ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0)
++              ACCESS_ONCE_RW(ads->ctl13) = set11nTries(i->rates, 0)
+                       | set11nTries(i->rates, 1)
+                       | set11nTries(i->rates, 2)
+                       | set11nTries(i->rates, 3)
+                       | (i->dur_update ? AR_DurUpdateEna : 0)
+                       | SM(0, AR_BurstDur);
+-              ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0)
++              ACCESS_ONCE_RW(ads->ctl14) = set11nRate(i->rates, 0)
+                       | set11nRate(i->rates, 1)
+                       | set11nRate(i->rates, 2)
+                       | set11nRate(i->rates, 3);
+       } else {
+-              ACCESS_ONCE(ads->ctl13) = 0;
+-              ACCESS_ONCE(ads->ctl14) = 0;
++              ACCESS_ONCE_RW(ads->ctl13) = 0;
++              ACCESS_ONCE_RW(ads->ctl14) = 0;
+       }
+       ads->ctl20 = 0;
+@@ -89,17 +89,17 @@
+       ctl17 = SM(i->keytype, AR_EncrType);
+       if (!i->is_first) {
+-              ACCESS_ONCE(ads->ctl11) = 0;
+-              ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore;
+-              ACCESS_ONCE(ads->ctl15) = 0;
+-              ACCESS_ONCE(ads->ctl16) = 0;
+-              ACCESS_ONCE(ads->ctl17) = ctl17;
+-              ACCESS_ONCE(ads->ctl18) = 0;
+-              ACCESS_ONCE(ads->ctl19) = 0;
++              ACCESS_ONCE_RW(ads->ctl11) = 0;
++              ACCESS_ONCE_RW(ads->ctl12) = i->is_last ? 0 : AR_TxMore;
++              ACCESS_ONCE_RW(ads->ctl15) = 0;
++              ACCESS_ONCE_RW(ads->ctl16) = 0;
++              ACCESS_ONCE_RW(ads->ctl17) = ctl17;
++              ACCESS_ONCE_RW(ads->ctl18) = 0;
++              ACCESS_ONCE_RW(ads->ctl19) = 0;
+               return;
+       }
+-      ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen)
++      ACCESS_ONCE_RW(ads->ctl11) = (i->pkt_len & AR_FrameLen)
+               | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
+               | SM(i->txpower, AR_XmitPower0)
+               | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
+@@ -135,26 +135,26 @@
+       val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S;
+       ctl12 |= SM(val, AR_PAPRDChainMask);
+-      ACCESS_ONCE(ads->ctl12) = ctl12;
+-      ACCESS_ONCE(ads->ctl17) = ctl17;
++      ACCESS_ONCE_RW(ads->ctl12) = ctl12;
++      ACCESS_ONCE_RW(ads->ctl17) = ctl17;
+-      ACCESS_ONCE(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0)
++      ACCESS_ONCE_RW(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0)
+               | set11nPktDurRTSCTS(i->rates, 1);
+-      ACCESS_ONCE(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2)
++      ACCESS_ONCE_RW(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2)
+               | set11nPktDurRTSCTS(i->rates, 3);
+-      ACCESS_ONCE(ads->ctl18) = set11nRateFlags(i->rates, 0)
++      ACCESS_ONCE_RW(ads->ctl18) = set11nRateFlags(i->rates, 0)
+               | set11nRateFlags(i->rates, 1)
+               | set11nRateFlags(i->rates, 2)
+               | set11nRateFlags(i->rates, 3)
+               | SM(i->rtscts_rate, AR_RTSCTSRate);
+-      ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
++      ACCESS_ONCE_RW(ads->ctl19) = AR_Not_Sounding;
+-      ACCESS_ONCE(ads->ctl20) = SM(i->txpower, AR_XmitPower1);
+-      ACCESS_ONCE(ads->ctl21) = SM(i->txpower, AR_XmitPower2);
+-      ACCESS_ONCE(ads->ctl22) = SM(i->txpower, AR_XmitPower3);
++      ACCESS_ONCE_RW(ads->ctl20) = SM(i->txpower, AR_XmitPower1);
++      ACCESS_ONCE_RW(ads->ctl21) = SM(i->txpower, AR_XmitPower2);
++      ACCESS_ONCE_RW(ads->ctl22) = SM(i->txpower, AR_XmitPower3);
+ }
+ static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/hw.h backports-3.18.1-1/drivers/net/wireless/ath/ath9k/hw.h
+--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/hw.h 2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/ath/ath9k/hw.h     2014-12-28 14:10:09.564888946 +0100
+@@ -630,7 +630,7 @@
+       /* ANI */
+       void (*ani_cache_ini_regs)(struct ath_hw *ah);
+-};
++} __no_const;
+ /**
+  * struct ath_spec_scan - parameters for Atheros spectral scan
+@@ -708,7 +708,7 @@
+ #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
+       void (*set_bt_ant_diversity)(struct ath_hw *hw, bool enable);
+ #endif
+-};
++} __no_const;
+ struct ath_nf_limits {
+       s16 max;
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/main.c backports-3.18.1-1/drivers/net/wireless/ath/ath9k/main.c
+--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/main.c       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/ath/ath9k/main.c   2014-12-28 14:24:49.169250593 +0100
+@@ -2454,16 +2454,18 @@
+       if (!ath9k_is_chanctx_enabled())
+               return;
+-      ath9k_ops.hw_scan                  = ath9k_hw_scan;
+-      ath9k_ops.cancel_hw_scan           = ath9k_cancel_hw_scan;
+-      ath9k_ops.remain_on_channel        = ath9k_remain_on_channel;
+-      ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel;
+-      ath9k_ops.add_chanctx              = ath9k_add_chanctx;
+-      ath9k_ops.remove_chanctx           = ath9k_remove_chanctx;
+-      ath9k_ops.change_chanctx           = ath9k_change_chanctx;
+-      ath9k_ops.assign_vif_chanctx       = ath9k_assign_vif_chanctx;
+-      ath9k_ops.unassign_vif_chanctx     = ath9k_unassign_vif_chanctx;
+-      ath9k_ops.mgd_prepare_tx           = ath9k_mgd_prepare_tx;
++      pax_open_kernel();
++      *(void **)&ath9k_ops.hw_scan                  = ath9k_hw_scan;
++      *(void **)&ath9k_ops.cancel_hw_scan           = ath9k_cancel_hw_scan;
++      *(void **)&ath9k_ops.remain_on_channel        = ath9k_remain_on_channel;
++      *(void **)&ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel;
++      *(void **)&ath9k_ops.add_chanctx              = ath9k_add_chanctx;
++      *(void **)&ath9k_ops.remove_chanctx           = ath9k_remove_chanctx;
++      *(void **)&ath9k_ops.change_chanctx           = ath9k_change_chanctx;
++      *(void **)&ath9k_ops.assign_vif_chanctx       = ath9k_assign_vif_chanctx;
++      *(void **)&ath9k_ops.unassign_vif_chanctx     = ath9k_unassign_vif_chanctx;
++      *(void **)&ath9k_ops.mgd_prepare_tx           = ath9k_mgd_prepare_tx;
++      pax_close_kernel();
+ }
+ #endif
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/b43/phy_lp.c backports-3.18.1-1/drivers/net/wireless/b43/phy_lp.c
+--- backports-3.18.1-1.org/drivers/net/wireless/b43/phy_lp.c   2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/b43/phy_lp.c       2014-12-28 14:10:09.564888946 +0100
+@@ -2502,7 +2502,7 @@
+ {
+       struct ssb_bus *bus = dev->dev->sdev->bus;
+-      static const struct b206x_channel *chandata = NULL;
++      const struct b206x_channel *chandata = NULL;
+       u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
+       u32 freqref, vco_freq, val1, val2, val3, timeout, timeoutref, count;
+       u16 old_comm15, scale;
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/iwlegacy/3945-mac.c backports-3.18.1-1/drivers/net/wireless/iwlegacy/3945-mac.c
+--- backports-3.18.1-1.org/drivers/net/wireless/iwlegacy/3945-mac.c    2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/iwlegacy/3945-mac.c        2014-12-28 14:10:09.564888946 +0100
+@@ -3633,7 +3633,9 @@
+        */
+       if (il3945_mod_params.disable_hw_scan) {
+               D_INFO("Disabling hw_scan\n");
+-              il3945_mac_ops.hw_scan = NULL;
++              pax_open_kernel();
++              *(void **)&il3945_mac_ops.hw_scan = NULL;
++              pax_close_kernel();
+       }
+       D_INFO("*** LOAD DRIVER ***\n");
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/iwlwifi/dvm/debugfs.c backports-3.18.1-1/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+--- backports-3.18.1-1.org/drivers/net/wireless/iwlwifi/dvm/debugfs.c  2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/iwlwifi/dvm/debugfs.c      2014-12-28 14:10:09.564888946 +0100
+@@ -188,7 +188,7 @@
+ {
+       struct iwl_priv *priv = file->private_data;
+       char buf[64];
+-      int buf_size;
++      size_t buf_size;
+       u32 offset, len;
+       memset(buf, 0, sizeof(buf));
+@@ -458,7 +458,7 @@
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       u32 reset_flag;
+       memset(buf, 0, sizeof(buf));
+@@ -539,7 +539,7 @@
+ {
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       int ht40;
+       memset(buf, 0, sizeof(buf));
+@@ -591,7 +591,7 @@
+ {
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       int value;
+       memset(buf, 0, sizeof(buf));
+@@ -683,10 +683,10 @@
+ DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
+ DEBUGFS_READ_FILE_OPS(current_sleep_command);
+-static const char *fmt_value = "  %-30s %10u\n";
+-static const char *fmt_hex   = "  %-30s       0x%02X\n";
+-static const char *fmt_table = "  %-30s %10u  %10u  %10u  %10u\n";
+-static const char *fmt_header =
++static const char fmt_value[] = "  %-30s %10u\n";
++static const char fmt_hex[]   = "  %-30s       0x%02X\n";
++static const char fmt_table[] = "  %-30s %10u  %10u  %10u  %10u\n";
++static const char fmt_header[] =
+       "%-32s    current  cumulative       delta         max\n";
+ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
+@@ -1856,7 +1856,7 @@
+ {
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       int clear;
+       memset(buf, 0, sizeof(buf));
+@@ -1901,7 +1901,7 @@
+ {
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       int trace;
+       memset(buf, 0, sizeof(buf));
+@@ -1972,7 +1972,7 @@
+ {
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       int missed;
+       memset(buf, 0, sizeof(buf));
+@@ -2013,7 +2013,7 @@
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       int plcp;
+       memset(buf, 0, sizeof(buf));
+@@ -2073,7 +2073,7 @@
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       int flush;
+       memset(buf, 0, sizeof(buf));
+@@ -2163,7 +2163,7 @@
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       int rts;
+       if (!priv->cfg->ht_params)
+@@ -2204,7 +2204,7 @@
+ {
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       memset(buf, 0, sizeof(buf));
+       buf_size = min(count, sizeof(buf) -  1);
+@@ -2238,7 +2238,7 @@
+       struct iwl_priv *priv = file->private_data;
+       u32 event_log_flag;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       /* check that the interface is up */
+       if (!iwl_is_ready(priv))
+@@ -2292,7 +2292,7 @@
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+       u32 calib_disabled;
+-      int buf_size;
++      size_t buf_size;
+       memset(buf, 0, sizeof(buf));
+       buf_size = min(count, sizeof(buf) - 1);
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/iwlwifi/pcie/trans.c backports-3.18.1-1/drivers/net/wireless/iwlwifi/pcie/trans.c
+--- backports-3.18.1-1.org/drivers/net/wireless/iwlwifi/pcie/trans.c   2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/iwlwifi/pcie/trans.c       2014-12-28 14:10:09.564888946 +0100
+@@ -1689,7 +1689,7 @@
+       struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       u32 reset_flag;
+       memset(buf, 0, sizeof(buf));
+@@ -1710,7 +1710,7 @@
+ {
+       struct iwl_trans *trans = file->private_data;
+       char buf[8];
+-      int buf_size;
++      size_t buf_size;
+       int csr;
+       memset(buf, 0, sizeof(buf));
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/mac80211_hwsim.c backports-3.18.1-1/drivers/net/wireless/mac80211_hwsim.c
+--- backports-3.18.1-1.org/drivers/net/wireless/mac80211_hwsim.c       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/mac80211_hwsim.c   2014-12-28 14:10:09.568888967 +0100
+@@ -2578,20 +2578,20 @@
+       if (channels < 1)
+               return -EINVAL;
+-      mac80211_hwsim_mchan_ops = mac80211_hwsim_ops;
+-      mac80211_hwsim_mchan_ops.hw_scan = mac80211_hwsim_hw_scan;
+-      mac80211_hwsim_mchan_ops.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan;
+-      mac80211_hwsim_mchan_ops.sw_scan_start = NULL;
+-      mac80211_hwsim_mchan_ops.sw_scan_complete = NULL;
+-      mac80211_hwsim_mchan_ops.remain_on_channel = mac80211_hwsim_roc;
+-      mac80211_hwsim_mchan_ops.cancel_remain_on_channel = mac80211_hwsim_croc;
+-      mac80211_hwsim_mchan_ops.add_chanctx = mac80211_hwsim_add_chanctx;
+-      mac80211_hwsim_mchan_ops.remove_chanctx = mac80211_hwsim_remove_chanctx;
+-      mac80211_hwsim_mchan_ops.change_chanctx = mac80211_hwsim_change_chanctx;
+-      mac80211_hwsim_mchan_ops.assign_vif_chanctx =
+-              mac80211_hwsim_assign_vif_chanctx;
+-      mac80211_hwsim_mchan_ops.unassign_vif_chanctx =
+-              mac80211_hwsim_unassign_vif_chanctx;
++      pax_open_kernel();
++      memcpy((void *)&mac80211_hwsim_mchan_ops, &mac80211_hwsim_ops, sizeof mac80211_hwsim_mchan_ops);
++      *(void **)&mac80211_hwsim_mchan_ops.hw_scan = mac80211_hwsim_hw_scan;
++      *(void **)&mac80211_hwsim_mchan_ops.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan;
++      *(void **)&mac80211_hwsim_mchan_ops.sw_scan_start = NULL;
++      *(void **)&mac80211_hwsim_mchan_ops.sw_scan_complete = NULL;
++      *(void **)&mac80211_hwsim_mchan_ops.remain_on_channel = mac80211_hwsim_roc;
++      *(void **)&mac80211_hwsim_mchan_ops.cancel_remain_on_channel = mac80211_hwsim_croc;
++      *(void **)&mac80211_hwsim_mchan_ops.add_chanctx = mac80211_hwsim_add_chanctx;
++      *(void **)&mac80211_hwsim_mchan_ops.remove_chanctx = mac80211_hwsim_remove_chanctx;
++      *(void **)&mac80211_hwsim_mchan_ops.change_chanctx = mac80211_hwsim_change_chanctx;
++      *(void **)&mac80211_hwsim_mchan_ops.assign_vif_chanctx = mac80211_hwsim_assign_vif_chanctx;
++      *(void **)&mac80211_hwsim_mchan_ops.unassign_vif_chanctx = mac80211_hwsim_unassign_vif_chanctx;
++      pax_close_kernel();
+       spin_lock_init(&hwsim_radio_lock);
+       INIT_LIST_HEAD(&hwsim_radios);
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/rndis_wlan.c backports-3.18.1-1/drivers/net/wireless/rndis_wlan.c
+--- backports-3.18.1-1.org/drivers/net/wireless/rndis_wlan.c   2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/rndis_wlan.c       2014-12-28 14:10:09.568888967 +0100
+@@ -1236,7 +1236,7 @@
+       netdev_dbg(usbdev->net, "%s(): %i\n", __func__, rts_threshold);
+-      if (rts_threshold < 0 || rts_threshold > 2347)
++      if (rts_threshold > 2347)
+               rts_threshold = 2347;
+       tmp = cpu_to_le32(rts_threshold);
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/rt2x00/rt2x00.h backports-3.18.1-1/drivers/net/wireless/rt2x00/rt2x00.h
+--- backports-3.18.1-1.org/drivers/net/wireless/rt2x00/rt2x00.h        2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/rt2x00/rt2x00.h    2014-12-28 14:10:09.568888967 +0100
+@@ -375,7 +375,7 @@
+        * for hardware which doesn't support hardware
+        * sequence counting.
+        */
+-      atomic_t seqno;
++      atomic_unchecked_t seqno;
+ };
+ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/rt2x00/rt2x00queue.c backports-3.18.1-1/drivers/net/wireless/rt2x00/rt2x00queue.c
+--- backports-3.18.1-1.org/drivers/net/wireless/rt2x00/rt2x00queue.c   2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/rt2x00/rt2x00queue.c       2014-12-28 14:10:09.568888967 +0100
+@@ -224,9 +224,9 @@
+        * sequence counter given by mac80211.
+        */
+       if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
+-              seqno = atomic_add_return(0x10, &intf->seqno);
++              seqno = atomic_add_return_unchecked(0x10, &intf->seqno);
+       else
+-              seqno = atomic_read(&intf->seqno);
++              seqno = atomic_read_unchecked(&intf->seqno);
+       hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+       hdr->seq_ctrl |= cpu_to_le16(seqno);
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ti/wl1251/sdio.c backports-3.18.1-1/drivers/net/wireless/ti/wl1251/sdio.c
+--- backports-3.18.1-1.org/drivers/net/wireless/ti/wl1251/sdio.c       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/ti/wl1251/sdio.c   2014-12-28 14:10:09.568888967 +0100
+@@ -282,13 +282,17 @@
+               irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+-              wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
+-              wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
++              pax_open_kernel();
++              *(void **)&wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
++              *(void **)&wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
++              pax_close_kernel();
+               wl1251_info("using dedicated interrupt line");
+       } else {
+-              wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
+-              wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
++              pax_open_kernel();
++              *(void **)&wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
++              *(void **)&wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
++              pax_close_kernel();
+               wl1251_info("using SDIO interrupt");
+       }
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ti/wl12xx/main.c backports-3.18.1-1/drivers/net/wireless/ti/wl12xx/main.c
+--- backports-3.18.1-1.org/drivers/net/wireless/ti/wl12xx/main.c       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/ti/wl12xx/main.c   2014-12-28 14:10:09.568888967 +0100
+@@ -656,7 +656,9 @@
+                      sizeof(wl->conf.mem));
+               /* read data preparation is only needed by wl127x */
+-              wl->ops->prepare_read = wl127x_prepare_read;
++              pax_open_kernel();
++              *(void **)&wl->ops->prepare_read = wl127x_prepare_read;
++              pax_close_kernel();
+               wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER,
+                             WL127X_IFTYPE_SR_VER,  WL127X_MAJOR_SR_VER,
+@@ -681,7 +683,9 @@
+                      sizeof(wl->conf.mem));
+               /* read data preparation is only needed by wl127x */
+-              wl->ops->prepare_read = wl127x_prepare_read;
++              pax_open_kernel();
++              *(void **)&wl->ops->prepare_read = wl127x_prepare_read;
++              pax_close_kernel();
+               wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER,
+                             WL127X_IFTYPE_SR_VER,  WL127X_MAJOR_SR_VER,
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ti/wl18xx/main.c backports-3.18.1-1/drivers/net/wireless/ti/wl18xx/main.c
+--- backports-3.18.1-1.org/drivers/net/wireless/ti/wl18xx/main.c       2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/ti/wl18xx/main.c   2014-12-28 14:10:09.568888967 +0100
+@@ -1916,8 +1916,10 @@
+       }
+       if (!checksum_param) {
+-              wl18xx_ops.set_rx_csum = NULL;
+-              wl18xx_ops.init_vif = NULL;
++              pax_open_kernel();
++              *(void **)&wl18xx_ops.set_rx_csum = NULL;
++              *(void **)&wl18xx_ops.init_vif = NULL;
++              pax_close_kernel();
+       }
+       /* Enable 11a Band only if we have 5G antennas */
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/zd1211rw/zd_usb.c backports-3.18.1-1/drivers/net/wireless/zd1211rw/zd_usb.c
+--- backports-3.18.1-1.org/drivers/net/wireless/zd1211rw/zd_usb.c      2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/zd1211rw/zd_usb.c  2014-12-28 14:10:09.568888967 +0100
+@@ -385,7 +385,7 @@
+ {
+       struct zd_usb *usb = urb->context;
+       struct zd_usb_interrupt *intr = &usb->intr;
+-      int len;
++      unsigned int len;
+       u16 int_num;
+       ZD_ASSERT(in_interrupt());
+diff -Naur backports-3.18.1-1.org/drivers/nfc/nfcwilink.c backports-3.18.1-1/drivers/nfc/nfcwilink.c
+--- backports-3.18.1-1.org/drivers/nfc/nfcwilink.c     2014-12-21 22:37:14.000000000 +0100
++++ backports-3.18.1-1/drivers/nfc/nfcwilink.c 2014-12-28 14:10:09.568888967 +0100
+@@ -497,7 +497,7 @@
+ static int nfcwilink_probe(struct platform_device *pdev)
+ {
+-      static struct nfcwilink *drv;
++      struct nfcwilink *drv;
+       int rc;
+       __u32 protocols;
+diff -Naur backports-3.18.1-1.org/include/linux/gracl_compat.h backports-3.18.1-1/include/linux/gracl_compat.h
+--- backports-3.18.1-1.org/include/linux/gracl_compat.h        1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/include/linux/gracl_compat.h    2014-12-28 14:10:09.684889542 +0100
+@@ -0,0 +1,156 @@
++#ifndef GR_ACL_COMPAT_H
++#define GR_ACL_COMPAT_H
++
++#include <linux/resource.h>
++#include <asm/resource.h>
++
++struct sprole_pw_compat {
++      compat_uptr_t rolename;
++      unsigned char salt[GR_SALT_LEN];
++      unsigned char sum[GR_SHA_LEN];
++};
++
++struct gr_hash_struct_compat {
++      compat_uptr_t table;
++      compat_uptr_t nametable;
++      compat_uptr_t first;
++      __u32 table_size;
++      __u32 used_size;
++      int type;
++};
++
++struct acl_subject_label_compat {
++      compat_uptr_t filename;
++      compat_ino_t inode;
++      __u32 device;
++      __u32 mode;
++      kernel_cap_t cap_mask;
++      kernel_cap_t cap_lower;
++      kernel_cap_t cap_invert_audit;
++
++      struct compat_rlimit res[GR_NLIMITS];
++      __u32 resmask;
++
++      __u8 user_trans_type;
++      __u8 group_trans_type;
++      compat_uptr_t user_transitions;
++      compat_uptr_t group_transitions;
++      __u16 user_trans_num;
++      __u16 group_trans_num;
++
++      __u32 sock_families[2];
++      __u32 ip_proto[8];
++      __u32 ip_type;
++      compat_uptr_t ips;
++      __u32 ip_num;
++      __u32 inaddr_any_override;
++
++      __u32 crashes;
++      compat_ulong_t expires;
++
++      compat_uptr_t parent_subject;
++      compat_uptr_t hash;
++      compat_uptr_t prev;
++      compat_uptr_t next;
++
++      compat_uptr_t obj_hash;
++      __u32 obj_hash_size;
++      __u16 pax_flags;
++};
++
++struct role_allowed_ip_compat {
++      __u32 addr;
++      __u32 netmask;
++
++      compat_uptr_t prev;
++      compat_uptr_t next;
++};
++
++struct role_transition_compat {
++      compat_uptr_t rolename;
++
++      compat_uptr_t prev;
++      compat_uptr_t next;
++};
++
++struct acl_role_label_compat {
++      compat_uptr_t rolename;
++      uid_t uidgid;
++      __u16 roletype;
++
++      __u16 auth_attempts;
++      compat_ulong_t expires;
++
++      compat_uptr_t root_label;
++      compat_uptr_t hash;
++
++      compat_uptr_t prev;
++      compat_uptr_t next;
++
++      compat_uptr_t transitions;
++      compat_uptr_t allowed_ips;
++      compat_uptr_t domain_children;
++      __u16 domain_child_num;
++
++      umode_t umask;
++
++      compat_uptr_t subj_hash;
++      __u32 subj_hash_size;
++};
++
++struct user_acl_role_db_compat {
++      compat_uptr_t r_table;
++      __u32 num_pointers;
++      __u32 num_roles;
++      __u32 num_domain_children;
++      __u32 num_subjects;
++      __u32 num_objects;
++};
++
++struct acl_object_label_compat {
++      compat_uptr_t filename;
++      compat_ino_t inode;
++      __u32 device;
++      __u32 mode;
++
++      compat_uptr_t nested;
++      compat_uptr_t globbed;
++
++      compat_uptr_t prev;
++      compat_uptr_t next;
++};
++
++struct acl_ip_label_compat {
++      compat_uptr_t iface;
++      __u32 addr;
++      __u32 netmask;
++      __u16 low, high;
++      __u8 mode;
++      __u32 type;
++      __u32 proto[8];
++
++      compat_uptr_t prev;
++      compat_uptr_t next;
++};
++
++struct gr_arg_compat {
++      struct user_acl_role_db_compat role_db;
++      unsigned char pw[GR_PW_LEN];
++      unsigned char salt[GR_SALT_LEN];
++      unsigned char sum[GR_SHA_LEN];
++      unsigned char sp_role[GR_SPROLE_LEN];
++      compat_uptr_t sprole_pws;
++      __u32 segv_device;
++      compat_ino_t segv_inode;
++      uid_t segv_uid;
++      __u16 num_sprole_pws;
++      __u16 mode;
++};
++
++struct gr_arg_wrapper_compat {
++      compat_uptr_t arg;
++      __u32 version;
++      __u32 size;
++};
++
++#endif
+diff -Naur backports-3.18.1-1.org/include/linux/gracl.h backports-3.18.1-1/include/linux/gracl.h
+--- backports-3.18.1-1.org/include/linux/gracl.h       1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/include/linux/gracl.h   2014-12-28 14:10:09.684889542 +0100
+@@ -0,0 +1,340 @@
++#ifndef GR_ACL_H
++#define GR_ACL_H
++
++#include <linux/grdefs.h>
++#include <linux/resource.h>
++#include <linux/capability.h>
++#include <linux/dcache.h>
++#include <asm/resource.h>
++
++/* Major status information */
++
++#define GR_VERSION  "grsecurity 3.0"
++#define GRSECURITY_VERSION 0x3000
++
++enum {
++      GR_SHUTDOWN = 0,
++      GR_ENABLE = 1,
++      GR_SPROLE = 2,
++      GR_OLDRELOAD = 3,
++      GR_SEGVMOD = 4,
++      GR_STATUS = 5,
++      GR_UNSPROLE = 6,
++      GR_PASSSET = 7,
++      GR_SPROLEPAM = 8,
++      GR_RELOAD = 9,
++};
++
++/* Password setup definitions
++ * kernel/grhash.c */
++enum {
++      GR_PW_LEN = 128,
++      GR_SALT_LEN = 16,
++      GR_SHA_LEN = 32,
++};
++
++enum {
++      GR_SPROLE_LEN = 64,
++};
++
++enum {
++      GR_NO_GLOB = 0,
++      GR_REG_GLOB,
++      GR_CREATE_GLOB
++};
++
++#define GR_NLIMITS 32
++
++/* Begin Data Structures */
++
++struct sprole_pw {
++      unsigned char *rolename;
++      unsigned char salt[GR_SALT_LEN];
++      unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
++};
++
++struct name_entry {
++      __u32 key;
++      ino_t inode;
++      dev_t device;
++      char *name;
++      __u16 len;
++      __u8 deleted;
++      struct name_entry *prev;
++      struct name_entry *next;
++};
++
++struct inodev_entry {
++      struct name_entry *nentry;
++      struct inodev_entry *prev;
++      struct inodev_entry *next;
++};
++
++struct acl_role_db {
++      struct acl_role_label **r_hash;
++      __u32 r_size;
++};
++
++struct inodev_db {
++      struct inodev_entry **i_hash;
++      __u32 i_size;
++};
++
++struct name_db {
++      struct name_entry **n_hash;
++      __u32 n_size;
++};
++
++struct crash_uid {
++      uid_t uid;
++      unsigned long expires;
++};
++
++struct gr_hash_struct {
++      void **table;
++      void **nametable;
++      void *first;
++      __u32 table_size;
++      __u32 used_size;
++      int type;
++};
++
++/* Userspace Grsecurity ACL data structures */
++
++struct acl_subject_label {
++      char *filename;
++      ino_t inode;
++      dev_t device;
++      __u32 mode;
++      kernel_cap_t cap_mask;
++      kernel_cap_t cap_lower;
++      kernel_cap_t cap_invert_audit;
++
++      struct rlimit res[GR_NLIMITS];
++      __u32 resmask;
++
++      __u8 user_trans_type;
++      __u8 group_trans_type;
++      uid_t *user_transitions;
++      gid_t *group_transitions;
++      __u16 user_trans_num;
++      __u16 group_trans_num;
++
++      __u32 sock_families[2];
++      __u32 ip_proto[8];
++      __u32 ip_type;
++      struct acl_ip_label **ips;
++      __u32 ip_num;
++      __u32 inaddr_any_override;
++
++      __u32 crashes;
++      unsigned long expires;
++
++      struct acl_subject_label *parent_subject;
++      struct gr_hash_struct *hash;
++      struct acl_subject_label *prev;
++      struct acl_subject_label *next;
++
++      struct acl_object_label **obj_hash;
++      __u32 obj_hash_size;
++      __u16 pax_flags;
++};
++
++struct role_allowed_ip {
++      __u32 addr;
++      __u32 netmask;
++
++      struct role_allowed_ip *prev;
++      struct role_allowed_ip *next;
++};
++
++struct role_transition {
++      char *rolename;
++
++      struct role_transition *prev;
++      struct role_transition *next;
++};
++
++struct acl_role_label {
++      char *rolename;
++      uid_t uidgid;
++      __u16 roletype;
++
++      __u16 auth_attempts;
++      unsigned long expires;
++
++      struct acl_subject_label *root_label;
++      struct gr_hash_struct *hash;
++
++      struct acl_role_label *prev;
++      struct acl_role_label *next;
++
++      struct role_transition *transitions;
++      struct role_allowed_ip *allowed_ips;
++      uid_t *domain_children;
++      __u16 domain_child_num;
++
++      umode_t umask;
++
++      struct acl_subject_label **subj_hash;
++      __u32 subj_hash_size;
++};
++
++struct user_acl_role_db {
++      struct acl_role_label **r_table;
++      __u32 num_pointers;             /* Number of allocations to track */
++      __u32 num_roles;                /* Number of roles */
++      __u32 num_domain_children;      /* Number of domain children */
++      __u32 num_subjects;             /* Number of subjects */
++      __u32 num_objects;              /* Number of objects */
++};
++
++struct acl_object_label {
++      char *filename;
++      ino_t inode;
++      dev_t device;
++      __u32 mode;
++
++      struct acl_subject_label *nested;
++      struct acl_object_label *globbed;
++
++      /* next two structures not used */
++
++      struct acl_object_label *prev;
++      struct acl_object_label *next;
++};
++
++struct acl_ip_label {
++      char *iface;
++      __u32 addr;
++      __u32 netmask;
++      __u16 low, high;
++      __u8 mode;
++      __u32 type;
++      __u32 proto[8];
++
++      /* next two structures not used */
++
++      struct acl_ip_label *prev;
++      struct acl_ip_label *next;
++};
++
++struct gr_arg {
++      struct user_acl_role_db role_db;
++      unsigned char pw[GR_PW_LEN];
++      unsigned char salt[GR_SALT_LEN];
++      unsigned char sum[GR_SHA_LEN];
++      unsigned char sp_role[GR_SPROLE_LEN];
++      struct sprole_pw *sprole_pws;
++      dev_t segv_device;
++      ino_t segv_inode;
++      uid_t segv_uid;
++      __u16 num_sprole_pws;
++      __u16 mode;
++};
++
++struct gr_arg_wrapper {
++      struct gr_arg *arg;
++      __u32 version;
++      __u32 size;
++};
++
++struct subject_map {
++      struct acl_subject_label *user;
++      struct acl_subject_label *kernel;
++      struct subject_map *prev;
++      struct subject_map *next;
++};
++
++struct acl_subj_map_db {
++      struct subject_map **s_hash;
++      __u32 s_size;
++};
++
++struct gr_policy_state {
++      struct sprole_pw **acl_special_roles;
++      __u16 num_sprole_pws;
++      struct acl_role_label *kernel_role;
++      struct acl_role_label *role_list;
++      struct acl_role_label *default_role;
++      struct acl_role_db acl_role_set;
++      struct acl_subj_map_db subj_map_set;
++      struct name_db name_set;
++      struct inodev_db inodev_set;
++};
++
++struct gr_alloc_state {
++      unsigned long alloc_stack_next;
++      unsigned long alloc_stack_size;
++      void **alloc_stack;
++};
++
++struct gr_reload_state {
++      struct gr_policy_state oldpolicy;
++      struct gr_alloc_state oldalloc;
++      struct gr_policy_state newpolicy;
++      struct gr_alloc_state newalloc;
++      struct gr_policy_state *oldpolicy_ptr;
++      struct gr_alloc_state *oldalloc_ptr;
++      unsigned char oldmode;
++};
++
++/* End Data Structures Section */
++
++/* Hash functions generated by empirical testing by Brad Spengler
++   Makes good use of the low bits of the inode.  Generally 0-1 times
++   in loop for successful match.  0-3 for unsuccessful match.
++   Shift/add algorithm with modulus of table size and an XOR*/
++
++static __inline__ unsigned int
++gr_rhash(const uid_t uid, const __u16 type, const unsigned int sz)
++{
++      return ((((uid + type) << (16 + type)) ^ uid) % sz);
++}
++
++ static __inline__ unsigned int
++gr_shash(const struct acl_subject_label *userp, const unsigned int sz)
++{
++      return ((const unsigned long)userp % sz);
++}
++
++static __inline__ unsigned int
++gr_fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
++{
++      return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
++}
++
++static __inline__ unsigned int
++gr_nhash(const char *name, const __u16 len, const unsigned int sz)
++{
++      return full_name_hash((const unsigned char *)name, len) % sz;
++}
++
++#define FOR_EACH_SUBJECT_START(role,subj,iter) \
++      subj = NULL; \
++      iter = 0; \
++      while (iter < role->subj_hash_size) { \
++              if (subj == NULL) \
++                      subj = role->subj_hash[iter]; \
++              if (subj == NULL) { \
++                      iter++; \
++                      continue; \
++              }
++
++#define FOR_EACH_SUBJECT_END(subj,iter) \
++              subj = subj->next; \
++              if (subj == NULL) \
++                      iter++; \
++      }
++
++
++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
++      subj = role->hash->first; \
++      while (subj != NULL) {
++
++#define FOR_EACH_NESTED_SUBJECT_END(subj) \
++              subj = subj->next; \
++      }
++
++#endif
++
+diff -Naur backports-3.18.1-1.org/include/linux/gralloc.h backports-3.18.1-1/include/linux/gralloc.h
+--- backports-3.18.1-1.org/include/linux/gralloc.h     1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/include/linux/gralloc.h 2014-12-28 14:10:09.684889542 +0100
+@@ -0,0 +1,9 @@
++#ifndef __GRALLOC_H
++#define __GRALLOC_H
++
++void acl_free_all(void);
++int acl_alloc_stack_init(unsigned long size);
++void *acl_alloc(unsigned long len);
++void *acl_alloc_num(unsigned long num, unsigned long len);
++
++#endif
+diff -Naur backports-3.18.1-1.org/include/linux/grdefs.h backports-3.18.1-1/include/linux/grdefs.h
+--- backports-3.18.1-1.org/include/linux/grdefs.h      1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/include/linux/grdefs.h  2014-12-28 14:10:09.688889562 +0100
+@@ -0,0 +1,140 @@
++#ifndef GRDEFS_H
++#define GRDEFS_H
++
++/* Begin grsecurity status declarations */
++
++enum {
++      GR_READY = 0x01,
++      GR_STATUS_INIT = 0x00   // disabled state
++};
++
++/* Begin  ACL declarations */
++
++/* Role flags */
++
++enum {
++      GR_ROLE_USER = 0x0001,
++      GR_ROLE_GROUP = 0x0002,
++      GR_ROLE_DEFAULT = 0x0004,
++      GR_ROLE_SPECIAL = 0x0008,
++      GR_ROLE_AUTH = 0x0010,
++      GR_ROLE_NOPW = 0x0020,
++      GR_ROLE_GOD = 0x0040,
++      GR_ROLE_LEARN = 0x0080,
++      GR_ROLE_TPE = 0x0100,
++      GR_ROLE_DOMAIN = 0x0200,
++      GR_ROLE_PAM = 0x0400,
++      GR_ROLE_PERSIST = 0x0800
++};
++
++/* ACL Subject and Object mode flags */
++enum {
++      GR_DELETED = 0x80000000
++};
++
++/* ACL Object-only mode flags */
++enum {
++      GR_READ         = 0x00000001,
++      GR_APPEND       = 0x00000002,
++      GR_WRITE        = 0x00000004,
++      GR_EXEC         = 0x00000008,
++      GR_FIND         = 0x00000010,
++      GR_INHERIT      = 0x00000020,
++      GR_SETID        = 0x00000040,
++      GR_CREATE       = 0x00000080,
++      GR_DELETE       = 0x00000100,
++      GR_LINK         = 0x00000200,
++      GR_AUDIT_READ   = 0x00000400,
++      GR_AUDIT_APPEND = 0x00000800,
++      GR_AUDIT_WRITE  = 0x00001000,
++      GR_AUDIT_EXEC   = 0x00002000,
++      GR_AUDIT_FIND   = 0x00004000,
++      GR_AUDIT_INHERIT= 0x00008000,
++      GR_AUDIT_SETID  = 0x00010000,
++      GR_AUDIT_CREATE = 0x00020000,
++      GR_AUDIT_DELETE = 0x00040000,
++      GR_AUDIT_LINK   = 0x00080000,
++      GR_PTRACERD     = 0x00100000,
++      GR_NOPTRACE     = 0x00200000,
++      GR_SUPPRESS     = 0x00400000,
++      GR_NOLEARN      = 0x00800000,
++      GR_INIT_TRANSFER= 0x01000000
++};
++
++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
++                 GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
++                 GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
++
++/* ACL subject-only mode flags */
++enum {
++      GR_KILL         = 0x00000001,
++      GR_VIEW         = 0x00000002,
++      GR_PROTECTED    = 0x00000004,
++      GR_LEARN        = 0x00000008,
++      GR_OVERRIDE     = 0x00000010,
++      /* just a placeholder, this mode is only used in userspace */
++      GR_DUMMY        = 0x00000020,
++      GR_PROTSHM      = 0x00000040,
++      GR_KILLPROC     = 0x00000080,
++      GR_KILLIPPROC   = 0x00000100,
++      /* just a placeholder, this mode is only used in userspace */
++      GR_NOTROJAN     = 0x00000200,
++      GR_PROTPROCFD   = 0x00000400,
++      GR_PROCACCT     = 0x00000800,
++      GR_RELAXPTRACE  = 0x00001000,
++      //GR_NESTED     = 0x00002000,
++      GR_INHERITLEARN = 0x00004000,
++      GR_PROCFIND     = 0x00008000,
++      GR_POVERRIDE    = 0x00010000,
++      GR_KERNELAUTH   = 0x00020000,
++      GR_ATSECURE     = 0x00040000,
++      GR_SHMEXEC      = 0x00080000
++};
++
++enum {
++      GR_PAX_ENABLE_SEGMEXEC  = 0x0001,
++      GR_PAX_ENABLE_PAGEEXEC  = 0x0002,
++      GR_PAX_ENABLE_MPROTECT  = 0x0004,
++      GR_PAX_ENABLE_RANDMMAP  = 0x0008,
++      GR_PAX_ENABLE_EMUTRAMP  = 0x0010,
++      GR_PAX_DISABLE_SEGMEXEC = 0x0100,
++      GR_PAX_DISABLE_PAGEEXEC = 0x0200,
++      GR_PAX_DISABLE_MPROTECT = 0x0400,
++      GR_PAX_DISABLE_RANDMMAP = 0x0800,
++      GR_PAX_DISABLE_EMUTRAMP = 0x1000,
++};
++
++enum {
++      GR_ID_USER      = 0x01,
++      GR_ID_GROUP     = 0x02,
++};
++
++enum {
++      GR_ID_ALLOW     = 0x01,
++      GR_ID_DENY      = 0x02,
++};
++
++#define GR_CRASH_RES  31
++#define GR_UIDTABLE_MAX 500
++
++/* begin resource learning section */
++enum {
++      GR_RLIM_CPU_BUMP = 60,
++      GR_RLIM_FSIZE_BUMP = 50000,
++      GR_RLIM_DATA_BUMP = 10000,
++      GR_RLIM_STACK_BUMP = 1000,
++      GR_RLIM_CORE_BUMP = 10000,
++      GR_RLIM_RSS_BUMP = 500000,
++      GR_RLIM_NPROC_BUMP = 1,
++      GR_RLIM_NOFILE_BUMP = 5,
++      GR_RLIM_MEMLOCK_BUMP = 50000,
++      GR_RLIM_AS_BUMP = 500000,
++      GR_RLIM_LOCKS_BUMP = 2,
++      GR_RLIM_SIGPENDING_BUMP = 5,
++      GR_RLIM_MSGQUEUE_BUMP = 10000,
++      GR_RLIM_NICE_BUMP = 1,
++      GR_RLIM_RTPRIO_BUMP = 1,
++      GR_RLIM_RTTIME_BUMP = 1000000
++};
++
++#endif
+diff -Naur backports-3.18.1-1.org/include/linux/grinternal.h backports-3.18.1-1/include/linux/grinternal.h
+--- backports-3.18.1-1.org/include/linux/grinternal.h  1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/include/linux/grinternal.h      2014-12-28 14:10:09.688889562 +0100
+@@ -0,0 +1,229 @@
++#ifndef __GRINTERNAL_H
++#define __GRINTERNAL_H
++
++#ifdef CONFIG_GRKERNSEC
++
++#include <linux/fs.h>
++#include <linux/mnt_namespace.h>
++#include <linux/nsproxy.h>
++#include <linux/gracl.h>
++#include <linux/grdefs.h>
++#include <linux/grmsg.h>
++
++void gr_add_learn_entry(const char *fmt, ...)
++      __attribute__ ((format (printf, 1, 2)));
++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
++                          const struct vfsmount *mnt);
++__u32 gr_check_create(const struct dentry *new_dentry,
++                           const struct dentry *parent,
++                           const struct vfsmount *mnt, const __u32 mode);
++int gr_check_protected_task(const struct task_struct *task);
++__u32 to_gr_audit(const __u32 reqmode);
++int gr_set_acls(const int type);
++int gr_acl_is_enabled(void);
++char gr_roletype_to_char(void);
++
++void gr_handle_alertkill(struct task_struct *task);
++char *gr_to_filename(const struct dentry *dentry,
++                          const struct vfsmount *mnt);
++char *gr_to_filename1(const struct dentry *dentry,
++                          const struct vfsmount *mnt);
++char *gr_to_filename2(const struct dentry *dentry,
++                          const struct vfsmount *mnt);
++char *gr_to_filename3(const struct dentry *dentry,
++                          const struct vfsmount *mnt);
++
++extern int grsec_enable_ptrace_readexec;
++extern int grsec_enable_harden_ptrace;
++extern int grsec_enable_link;
++extern int grsec_enable_fifo;
++extern int grsec_enable_execve;
++extern int grsec_enable_shm;
++extern int grsec_enable_execlog;
++extern int grsec_enable_signal;
++extern int grsec_enable_audit_ptrace;
++extern int grsec_enable_forkfail;
++extern int grsec_enable_time;
++extern int grsec_enable_rofs;
++extern int grsec_deny_new_usb;
++extern int grsec_enable_chroot_shmat;
++extern int grsec_enable_chroot_mount;
++extern int grsec_enable_chroot_double;
++extern int grsec_enable_chroot_pivot;
++extern int grsec_enable_chroot_chdir;
++extern int grsec_enable_chroot_chmod;
++extern int grsec_enable_chroot_mknod;
++extern int grsec_enable_chroot_fchdir;
++extern int grsec_enable_chroot_nice;
++extern int grsec_enable_chroot_execlog;
++extern int grsec_enable_chroot_caps;
++extern int grsec_enable_chroot_sysctl;
++extern int grsec_enable_chroot_unix;
++extern int grsec_enable_symlinkown;
++extern kgid_t grsec_symlinkown_gid;
++extern int grsec_enable_tpe;
++extern kgid_t grsec_tpe_gid;
++extern int grsec_enable_tpe_all;
++extern int grsec_enable_tpe_invert;
++extern int grsec_enable_socket_all;
++extern kgid_t grsec_socket_all_gid;
++extern int grsec_enable_socket_client;
++extern kgid_t grsec_socket_client_gid;
++extern int grsec_enable_socket_server;
++extern kgid_t grsec_socket_server_gid;
++extern kgid_t grsec_audit_gid;
++extern int grsec_enable_group;
++extern int grsec_enable_log_rwxmaps;
++extern int grsec_enable_mount;
++extern int grsec_enable_chdir;
++extern int grsec_resource_logging;
++extern int grsec_enable_blackhole;
++extern int grsec_lastack_retries;
++extern int grsec_enable_brute;
++extern int grsec_enable_harden_ipc;
++extern int grsec_lock;
++
++extern spinlock_t grsec_alert_lock;
++extern unsigned long grsec_alert_wtime;
++extern unsigned long grsec_alert_fyet;
++
++extern spinlock_t grsec_audit_lock;
++
++extern rwlock_t grsec_exec_file_lock;
++
++#define gr_task_fullpath(tsk) ((tsk)->exec_file ? \
++                      gr_to_filename2((tsk)->exec_file->f_path.dentry, \
++                      (tsk)->exec_file->f_path.mnt) : "/")
++
++#define gr_parent_task_fullpath(tsk) ((tsk)->real_parent->exec_file ? \
++                      gr_to_filename3((tsk)->real_parent->exec_file->f_path.dentry, \
++                      (tsk)->real_parent->exec_file->f_path.mnt) : "/")
++
++#define gr_task_fullpath0(tsk) ((tsk)->exec_file ? \
++                      gr_to_filename((tsk)->exec_file->f_path.dentry, \
++                      (tsk)->exec_file->f_path.mnt) : "/")
++
++#define gr_parent_task_fullpath0(tsk) ((tsk)->real_parent->exec_file ? \
++                      gr_to_filename1((tsk)->real_parent->exec_file->f_path.dentry, \
++                      (tsk)->real_parent->exec_file->f_path.mnt) : "/")
++
++#define proc_is_chrooted(tsk_a)  ((tsk_a)->gr_is_chrooted)
++
++#define have_same_root(tsk_a,tsk_b) ((tsk_a)->gr_chroot_dentry == (tsk_b)->gr_chroot_dentry)
++
++static inline bool gr_is_same_file(const struct file *file1, const struct file *file2)
++{
++      if (file1 && file2) {
++              const struct inode *inode1 = file1->f_path.dentry->d_inode;
++              const struct inode *inode2 = file2->f_path.dentry->d_inode;
++              if (inode1->i_ino == inode2->i_ino && inode1->i_sb->s_dev == inode2->i_sb->s_dev)
++                      return true;
++      }
++
++      return false;
++}
++
++#define GR_CHROOT_CAPS {{ \
++      CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
++      CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
++      CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
++      CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
++      CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
++      CAP_TO_MASK(CAP_IPC_OWNER) | CAP_TO_MASK(CAP_SETFCAP), \
++      CAP_TO_MASK(CAP_SYSLOG) | CAP_TO_MASK(CAP_MAC_ADMIN) }}
++
++#define security_learn(normal_msg,args...) \
++({ \
++      read_lock(&grsec_exec_file_lock); \
++      gr_add_learn_entry(normal_msg "\n", ## args); \
++      read_unlock(&grsec_exec_file_lock); \
++})
++
++enum {
++      GR_DO_AUDIT,
++      GR_DONT_AUDIT,
++      /* used for non-audit messages that we shouldn't kill the task on */
++      GR_DONT_AUDIT_GOOD
++};
++
++enum {
++      GR_TTYSNIFF,
++      GR_RBAC,
++      GR_RBAC_STR,
++      GR_STR_RBAC,
++      GR_RBAC_MODE2,
++      GR_RBAC_MODE3,
++      GR_FILENAME,
++      GR_SYSCTL_HIDDEN,
++      GR_NOARGS,
++      GR_ONE_INT,
++      GR_ONE_INT_TWO_STR,
++      GR_ONE_STR,
++      GR_STR_INT,
++      GR_TWO_STR_INT,
++      GR_TWO_INT,
++      GR_TWO_U64,
++      GR_THREE_INT,
++      GR_FIVE_INT_TWO_STR,
++      GR_TWO_STR,
++      GR_THREE_STR,
++      GR_FOUR_STR,
++      GR_STR_FILENAME,
++      GR_FILENAME_STR,
++      GR_FILENAME_TWO_INT,
++      GR_FILENAME_TWO_INT_STR,
++      GR_TEXTREL,
++      GR_PTRACE,
++      GR_RESOURCE,
++      GR_CAP,
++      GR_SIG,
++      GR_SIG2,
++      GR_CRASH1,
++      GR_CRASH2,
++      GR_PSACCT,
++      GR_RWXMAP,
++      GR_RWXMAPVMA
++};
++
++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
++#define gr_log_fs_rbac_mode3(audit, msg, dentry, mnt, str1, str2, str3) gr_log_varargs(audit, msg, GR_RBAC_MODE3, dentry, mnt, str1, str2, str3)
++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
++#define gr_log_two_u64(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_U64, num1, num2)
++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
++#define gr_log_int5_str2(audit, msg, num1, num2, str1, str2) gr_log_varargs(audit, msg, GR_FIVE_INT_TWO_STR, num1, num2, str1, str2)
++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
++#define gr_log_str2_int(audit, msg, str1, str2, num) gr_log_varargs(audit, msg, GR_TWO_STR_INT, str1, str2, num)
++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
++#define gr_log_fs_int2_str(audit, msg, dentry, mnt, num1, num2, str) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT_STR, dentry, mnt, num1, num2, str)
++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
++#define gr_log_sig_addr(audit, msg, str, addr) gr_log_varargs(audit, msg, GR_SIG, str, addr)
++#define gr_log_sig_task(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG2, task, num)
++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
++#define gr_log_procacct(audit, msg, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) gr_log_varargs(audit, msg, GR_PSACCT, task, num1, num2, num3, num4, num5, num6, num7, num8, num9)
++#define gr_log_rwxmap(audit, msg, str) gr_log_varargs(audit, msg, GR_RWXMAP, str)
++#define gr_log_rwxmap_vma(audit, msg, str) gr_log_varargs(audit, msg, GR_RWXMAPVMA, str)
++
++void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
++
++#endif
++
++#endif
+diff -Naur backports-3.18.1-1.org/include/linux/grmsg.h backports-3.18.1-1/include/linux/grmsg.h
+--- backports-3.18.1-1.org/include/linux/grmsg.h       1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/include/linux/grmsg.h   2014-12-28 14:10:09.688889562 +0100
+@@ -0,0 +1,117 @@
++#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u"
++#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u"
++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
++#define GR_STOPMOD_MSG "denied modification of module state by "
++#define GR_ROFS_BLOCKWRITE_MSG "denied write to block device %.950s by "
++#define GR_ROFS_MOUNT_MSG "denied writable mount of %.950s by "
++#define GR_IOPERM_MSG "denied use of ioperm() by "
++#define GR_IOPL_MSG "denied use of iopl() by "
++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
++#define GR_MEM_READWRITE_MSG "denied access of range %Lx -> %Lx in /dev/mem by "
++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
++#define GR_LEARN_AUDIT_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%lu\t%lu\t%.4095s\t%lu\t%pI4"
++#define GR_ID_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%c\t%d\t%d\t%d\t%pI4"
++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%pI4 %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
++#define GR_UNSAFESHARE_EXEC_ACL_MSG "denied exec with cloned fs of %.950s by "
++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
++#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
++#define GR_EXEC_TPE_MSG "denied untrusted exec (due to %.70s) of %.950s by "
++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
++#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
++#define GR_CHROOT_FHANDLE_MSG "denied use of file handles inside chroot by "
++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
++#define GR_SETXATTR_ACL_MSG "%s setting extended attribute of %.950s by "
++#define GR_REMOVEXATTR_ACL_MSG "%s removing extended attribute of %.950s by "
++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
++#define GR_INITF_ACL_MSG "init_variables() failed %s by "
++#define GR_DISABLED_ACL_MSG "Error loading %s, trying to run kernel with acls disabled. To disable acls at startup use <kernel image name> gracl=off from your boot loader"
++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbage by "
++#define GR_SHUTS_ACL_MSG "shutdown auth success for "
++#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
++#define GR_ENABLEF_ACL_MSG "unable to load %s for "
++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
++#define GR_RELOADF_ACL_MSG "failed reload of %s for "
++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
++#define GR_SPROLEF_ACL_MSG "special role %s failure for "
++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
++#define GR_INVMODE_ACL_MSG "invalid mode %d by "
++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
++#define GR_FAILFORK_MSG "failed fork with errno %s by "
++#define GR_NICE_CHROOT_MSG "denied priority change by "
++#define GR_UNISIGLOG_MSG "%.32s occurred at %p in "
++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
++#define GR_TIME_MSG "time set by "
++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
++#define GR_SOCK_NOINET_MSG "denied socket(%.16s,%.16s,%d) by "
++#define GR_BIND_MSG "denied bind() by "
++#define GR_CONNECT_MSG "denied connect() by "
++#define GR_BIND_ACL_MSG "denied bind() to %pI4 port %u sock type %.16s protocol %.16s by "
++#define GR_CONNECT_ACL_MSG "denied connect() to %pI4 port %u sock type %.16s protocol %.16s by "
++#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%pI4\t%u\t%u\t%u\t%u\t%pI4"
++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
++#define GR_CAP_ACL_MSG "use of %s denied for "
++#define GR_CAP_CHROOT_MSG "use of %s in chroot denied for "
++#define GR_CAP_ACL_MSG2 "use of %s permitted for "
++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
++#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
++#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
++#define GR_RWXMMAP_MSG "denied RWX mmap of %.950s by "
++#define GR_RWXMPROTECT_MSG "denied RWX mprotect of %.950s by "
++#define GR_TEXTREL_AUDIT_MSG "denied text relocation in %.950s, VMA:0x%08lx 0x%08lx by "
++#define GR_PTGNUSTACK_MSG "denied marking stack executable as requested by PT_GNU_STACK marking in %.950s by "
++#define GR_VM86_MSG "denied use of vm86 by "
++#define GR_PTRACE_AUDIT_MSG "process %.950s(%.16s:%d) attached to via ptrace by "
++#define GR_PTRACE_READEXEC_MSG "denied ptrace of unreadable binary %.950s by "
++#define GR_INIT_TRANSFER_MSG "persistent special role transferred privilege to init by "
++#define GR_BADPROCPID_MSG "denied read of sensitive /proc/pid/%s entry via fd passed across exec by "
++#define GR_SYMLINKOWNER_MSG "denied following symlink %.950s since symlink owner %u does not match target owner %u, by "
++#define GR_BRUTE_DAEMON_MSG "bruteforce prevention initiated for the next 30 minutes or until service restarted, stalling each fork 30 seconds.  Please investigate the crash report for "
++#define GR_BRUTE_SUID_MSG "bruteforce prevention initiated due to crash of %.950s against uid %u, banning suid/sgid execs for %u minutes.  Please investigate the crash report for "
++#define GR_IPC_DENIED_MSG "denied %s of overly-permissive IPC object with creator uid %u by "
++#define GR_MSRWRITE_MSG "denied write to CPU MSR by "
+diff -Naur backports-3.18.1-1.org/include/linux/grsecurity.h backports-3.18.1-1/include/linux/grsecurity.h
+--- backports-3.18.1-1.org/include/linux/grsecurity.h  1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/include/linux/grsecurity.h      2014-12-28 14:10:09.688889562 +0100
+@@ -0,0 +1,254 @@
++#ifndef GR_SECURITY_H
++#define GR_SECURITY_H
++#include <linux/fs.h>
++#include <linux/fs_struct.h>
++#include <linux/binfmts.h>
++#include <linux/gracl.h>
++
++/* notify of brain-dead configs */
++#if defined(CONFIG_GRKERNSEC_PROC_USER) && defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
++#error "CONFIG_GRKERNSEC_PROC_USER and CONFIG_GRKERNSEC_PROC_USERGROUP cannot both be enabled."
++#endif
++#if defined(CONFIG_GRKERNSEC_PROC) && !defined(CONFIG_GRKERNSEC_PROC_USER) && !defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
++#error "CONFIG_GRKERNSEC_PROC enabled, but neither CONFIG_GRKERNSEC_PROC_USER nor CONFIG_GRKERNSEC_PROC_USERGROUP enabled"
++#endif
++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
++#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
++#endif
++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
++#endif
++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
++#error "CONFIG_PAX enabled, but no PaX options are enabled."
++#endif
++
++int gr_handle_new_usb(void);
++
++void gr_handle_brute_attach(int dumpable);
++void gr_handle_brute_check(void);
++void gr_handle_kernel_exploit(void);
++
++char gr_roletype_to_char(void);
++
++int gr_proc_is_restricted(void);
++
++int gr_acl_enable_at_secure(void);
++
++int gr_check_user_change(kuid_t real, kuid_t effective, kuid_t fs);
++int gr_check_group_change(kgid_t real, kgid_t effective, kgid_t fs);
++
++int gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap);
++
++void gr_del_task_from_ip_table(struct task_struct *p);
++
++int gr_pid_is_chrooted(struct task_struct *p);
++int gr_handle_chroot_fowner(struct pid *pid, enum pid_type type);
++int gr_handle_chroot_nice(void);
++int gr_handle_chroot_sysctl(const int op);
++int gr_handle_chroot_setpriority(struct task_struct *p,
++                                      const int niceval);
++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
++int gr_chroot_fhandle(void);
++int gr_handle_chroot_chroot(const struct dentry *dentry,
++                                 const struct vfsmount *mnt);
++void gr_handle_chroot_chdir(const struct path *path);
++int gr_handle_chroot_chmod(const struct dentry *dentry,
++                                const struct vfsmount *mnt, const int mode);
++int gr_handle_chroot_mknod(const struct dentry *dentry,
++                                const struct vfsmount *mnt, const int mode);
++int gr_handle_chroot_mount(const struct dentry *dentry,
++                                const struct vfsmount *mnt,
++                                const char *dev_name);
++int gr_handle_chroot_pivot(void);
++int gr_handle_chroot_unix(const pid_t pid);
++
++int gr_handle_rawio(const struct inode *inode);
++
++void gr_handle_ioperm(void);
++void gr_handle_iopl(void);
++void gr_handle_msr_write(void);
++
++umode_t gr_acl_umask(void);
++
++int gr_tpe_allow(const struct file *file);
++
++void gr_set_chroot_entries(struct task_struct *task, const struct path *path);
++void gr_clear_chroot_entries(struct task_struct *task);
++
++void gr_log_forkfail(const int retval);
++void gr_log_timechange(void);
++void gr_log_signal(const int sig, const void *addr, const struct task_struct *t);
++void gr_log_chdir(const struct dentry *dentry,
++                       const struct vfsmount *mnt);
++void gr_log_chroot_exec(const struct dentry *dentry,
++                             const struct vfsmount *mnt);
++void gr_log_remount(const char *devname, const int retval);
++void gr_log_unmount(const char *devname, const int retval);
++void gr_log_mount(const char *from, const char *to, const int retval);
++void gr_log_textrel(struct vm_area_struct *vma);
++void gr_log_ptgnustack(struct file *file);
++void gr_log_rwxmmap(struct file *file);
++void gr_log_rwxmprotect(struct vm_area_struct *vma);
++
++int gr_handle_follow_link(const struct inode *parent,
++                               const struct inode *inode,
++                               const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++int gr_handle_fifo(const struct dentry *dentry,
++                        const struct vfsmount *mnt,
++                        const struct dentry *dir, const int flag,
++                        const int acc_mode);
++int gr_handle_hardlink(const struct dentry *dentry,
++                            const struct vfsmount *mnt,
++                            struct inode *inode,
++                            const int mode, const struct filename *to);
++
++int gr_is_capable(const int cap);
++int gr_is_capable_nolog(const int cap);
++int gr_task_is_capable(const struct task_struct *task, const struct cred *cred, const int cap);
++int gr_task_is_capable_nolog(const struct task_struct *task, const int cap);
++
++void gr_copy_label(struct task_struct *tsk);
++void gr_handle_crash(struct task_struct *task, const int sig);
++int gr_handle_signal(const struct task_struct *p, const int sig);
++int gr_check_crash_uid(const kuid_t uid);
++int gr_check_protected_task(const struct task_struct *task);
++int gr_check_protected_task_fowner(struct pid *pid, enum pid_type type);
++int gr_acl_handle_mmap(const struct file *file,
++                            const unsigned long prot);
++int gr_acl_handle_mprotect(const struct file *file,
++                                const unsigned long prot);
++int gr_check_hidden_task(const struct task_struct *tsk);
++__u32 gr_acl_handle_truncate(const struct dentry *dentry,
++                                  const struct vfsmount *mnt);
++__u32 gr_acl_handle_utime(const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++__u32 gr_acl_handle_access(const struct dentry *dentry,
++                                const struct vfsmount *mnt, const int fmode);
++__u32 gr_acl_handle_chmod(const struct dentry *dentry,
++                               const struct vfsmount *mnt, umode_t *mode);
++__u32 gr_acl_handle_chown(const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++__u32 gr_acl_handle_setxattr(const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++__u32 gr_acl_handle_removexattr(const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++int gr_handle_ptrace(struct task_struct *task, const long request);
++int gr_handle_proc_ptrace(struct task_struct *task);
++__u32 gr_acl_handle_execve(const struct dentry *dentry,
++                                const struct vfsmount *mnt);
++int gr_check_crash_exec(const struct file *filp);
++int gr_acl_is_enabled(void);
++void gr_set_role_label(struct task_struct *task, const kuid_t uid,
++                            const kgid_t gid);
++int gr_set_proc_label(const struct dentry *dentry,
++                      const struct vfsmount *mnt,
++                      const int unsafe_flags);
++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
++                              const struct vfsmount *mnt);
++__u32 gr_acl_handle_open(const struct dentry *dentry,
++                              const struct vfsmount *mnt, int acc_mode);
++__u32 gr_acl_handle_creat(const struct dentry *dentry,
++                               const struct dentry *p_dentry,
++                               const struct vfsmount *p_mnt,
++                               int open_flags, int acc_mode, const int imode);
++void gr_handle_create(const struct dentry *dentry,
++                           const struct vfsmount *mnt);
++void gr_handle_proc_create(const struct dentry *dentry,
++                         const struct inode *inode);
++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
++                               const struct dentry *parent_dentry,
++                               const struct vfsmount *parent_mnt,
++                               const int mode);
++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
++                               const struct dentry *parent_dentry,
++                               const struct vfsmount *parent_mnt);
++__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
++                               const struct vfsmount *mnt);
++void gr_handle_delete(const ino_t ino, const dev_t dev);
++__u32 gr_acl_handle_unlink(const struct dentry *dentry,
++                                const struct vfsmount *mnt);
++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
++                                 const struct dentry *parent_dentry,
++                                 const struct vfsmount *parent_mnt,
++                                 const struct filename *from);
++__u32 gr_acl_handle_link(const struct dentry *new_dentry,
++                              const struct dentry *parent_dentry,
++                              const struct vfsmount *parent_mnt,
++                              const struct dentry *old_dentry,
++                              const struct vfsmount *old_mnt, const struct filename *to);
++int gr_handle_symlink_owner(const struct path *link, const struct inode *target);
++int gr_acl_handle_rename(struct dentry *new_dentry,
++                              struct dentry *parent_dentry,
++                              const struct vfsmount *parent_mnt,
++                              struct dentry *old_dentry,
++                              struct inode *old_parent_inode,
++                              struct vfsmount *old_mnt, const struct filename *newname, unsigned int flags);
++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
++                              struct dentry *old_dentry,
++                              struct dentry *new_dentry,
++                              struct vfsmount *mnt, const __u8 replace, unsigned int flags);
++__u32 gr_check_link(const struct dentry *new_dentry,
++                         const struct dentry *parent_dentry,
++                         const struct vfsmount *parent_mnt,
++                         const struct dentry *old_dentry,
++                         const struct vfsmount *old_mnt);
++int gr_acl_handle_filldir(const struct file *file, const char *name,
++                               const unsigned int namelen, const ino_t ino);
++
++__u32 gr_acl_handle_unix(const struct dentry *dentry,
++                              const struct vfsmount *mnt);
++void gr_acl_handle_exit(void);
++void gr_acl_handle_psacct(struct task_struct *task, const long code);
++int gr_acl_handle_procpidmem(const struct task_struct *task);
++int gr_handle_rofs_mount(struct dentry *dentry, struct vfsmount *mnt, int mnt_flags);
++int gr_handle_rofs_blockwrite(struct dentry *dentry, struct vfsmount *mnt, int acc_mode);
++void gr_audit_ptrace(struct task_struct *task);
++dev_t gr_get_dev_from_dentry(struct dentry *dentry);
++void gr_put_exec_file(struct task_struct *task);
++
++int gr_ptrace_readexec(struct file *file, int unsafe_flags);
++
++#if defined(CONFIG_GRKERNSEC) && (defined(CONFIG_GRKERNSEC_RESLOG) || !defined(CONFIG_GRKERNSEC_NO_RBAC))
++extern void gr_learn_resource(const struct task_struct *task, const int res,
++                            const unsigned long wanted, const int gt);
++#else
++static inline void gr_learn_resource(const struct task_struct *task, const int res,
++                                   const unsigned long wanted, const int gt)
++{
++}
++#endif
++
++#ifdef CONFIG_GRKERNSEC_RESLOG
++extern void gr_log_resource(const struct task_struct *task, const int res,
++                                 const unsigned long wanted, const int gt);
++#else
++static inline void gr_log_resource(const struct task_struct *task, const int res,
++                                 const unsigned long wanted, const int gt)
++{
++}
++#endif
++
++#ifdef CONFIG_GRKERNSEC
++void task_grsec_rbac(struct seq_file *m, struct task_struct *p);
++void gr_handle_vm86(void);
++void gr_handle_mem_readwrite(u64 from, u64 to);
++
++void gr_log_badprocpid(const char *entry);
++
++extern int grsec_enable_dmesg;
++extern int grsec_disable_privio;
++
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
++extern kgid_t grsec_proc_gid;
++#endif
++
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
++extern int grsec_enable_chroot_findtask;
++#endif
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern int grsec_enable_setxid;
++#endif
++#endif
++
++#endif
+diff -Naur backports-3.18.1-1.org/include/linux/grsock.h backports-3.18.1-1/include/linux/grsock.h
+--- backports-3.18.1-1.org/include/linux/grsock.h      1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/include/linux/grsock.h  2014-12-28 14:10:09.688889562 +0100
+@@ -0,0 +1,19 @@
++#ifndef __GRSOCK_H
++#define __GRSOCK_H
++
++extern void gr_attach_curr_ip(const struct sock *sk);
++extern int gr_handle_sock_all(const int family, const int type,
++                            const int protocol);
++extern int gr_handle_sock_server(const struct sockaddr *sck);
++extern int gr_handle_sock_server_other(const struct sock *sck);
++extern int gr_handle_sock_client(const struct sockaddr *sck);
++extern int gr_search_connect(struct socket * sock,
++                           struct sockaddr_in * addr);
++extern int gr_search_bind(struct socket * sock,
++                        struct sockaddr_in * addr);
++extern int gr_search_listen(struct socket * sock);
++extern int gr_search_accept(struct socket * sock);
++extern int gr_search_socket(const int domain, const int type,
++                          const int protocol);
++
++#endif
+diff -Naur backports-3.18.1-1.org/include/linux/unaligned/access_ok.h backports-3.18.1-1/include/linux/unaligned/access_ok.h
+--- backports-3.18.1-1.org/include/linux/unaligned/access_ok.h 2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/include/linux/unaligned/access_ok.h     2014-12-28 14:10:09.712889681 +0100
+@@ -4,34 +4,34 @@
+ #include <linux/kernel.h>
+ #include <asm/byteorder.h>
+-static inline u16 get_unaligned_le16(const void *p)
++static inline u16 __intentional_overflow(-1) get_unaligned_le16(const void *p)
+ {
+-      return le16_to_cpup((__le16 *)p);
++      return le16_to_cpup((const __le16 *)p);
+ }
+-static inline u32 get_unaligned_le32(const void *p)
++static inline u32 __intentional_overflow(-1) get_unaligned_le32(const void *p)
+ {
+-      return le32_to_cpup((__le32 *)p);
++      return le32_to_cpup((const __le32 *)p);
+ }
+-static inline u64 get_unaligned_le64(const void *p)
++static inline u64 __intentional_overflow(-1) get_unaligned_le64(const void *p)
+ {
+-      return le64_to_cpup((__le64 *)p);
++      return le64_to_cpup((const __le64 *)p);
+ }
+-static inline u16 get_unaligned_be16(const void *p)
++static inline u16 __intentional_overflow(-1) get_unaligned_be16(const void *p)
+ {
+-      return be16_to_cpup((__be16 *)p);
++      return be16_to_cpup((const __be16 *)p);
+ }
+-static inline u32 get_unaligned_be32(const void *p)
++static inline u32 __intentional_overflow(-1) get_unaligned_be32(const void *p)
+ {
+-      return be32_to_cpup((__be32 *)p);
++      return be32_to_cpup((const __be32 *)p);
+ }
+-static inline u64 get_unaligned_be64(const void *p)
++static inline u64 __intentional_overflow(-1) get_unaligned_be64(const void *p)
+ {
+-      return be64_to_cpup((__be64 *)p);
++      return be64_to_cpup((const __be64 *)p);
+ }
+ static inline void put_unaligned_le16(u16 val, void *p)
+diff -Naur backports-3.18.1-1.org/include/media/v4l2-dev.h backports-3.18.1-1/include/media/v4l2-dev.h
+--- backports-3.18.1-1.org/include/media/v4l2-dev.h    2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/include/media/v4l2-dev.h        2014-12-28 14:10:09.716889709 +0100
+@@ -75,7 +75,7 @@
+       int (*mmap) (struct file *, struct vm_area_struct *);
+       int (*open) (struct file *);
+       int (*release) (struct file *);
+-};
++} __do_const;
+ /*
+  * Newer version of video_device, handled by videodev2.c
+diff -Naur backports-3.18.1-1.org/include/media/v4l2-device.h backports-3.18.1-1/include/media/v4l2-device.h
+--- backports-3.18.1-1.org/include/media/v4l2-device.h 2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/include/media/v4l2-device.h     2014-12-28 14:10:09.716889709 +0100
+@@ -95,7 +95,7 @@
+    this function returns 0. If the name ends with a digit (e.g. cx18),
+    then the name will be set to cx18-0 since cx180 looks really odd. */
+ int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
+-                                              atomic_t *instance);
++                                              atomic_unchecked_t *instance);
+ /* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects.
+    Since the parent disappears this ensures that v4l2_dev doesn't have an
+diff -Naur backports-3.18.1-1.org/include/net/bluetooth/l2cap.h backports-3.18.1-1/include/net/bluetooth/l2cap.h
+--- backports-3.18.1-1.org/include/net/bluetooth/l2cap.h       2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/include/net/bluetooth/l2cap.h   2014-12-28 14:10:09.716889709 +0100
+@@ -608,7 +608,7 @@
+                                                    unsigned char *kdata,
+                                                    struct iovec *iov,
+                                                    int len);
+-};
++} __do_const;
+ struct l2cap_conn {
+       struct hci_conn         *hcon;
+diff -Naur backports-3.18.1-1.org/include/net/mac80211.h backports-3.18.1-1/include/net/mac80211.h
+--- backports-3.18.1-1.org/include/net/mac80211.h      2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/include/net/mac80211.h  2014-12-28 14:10:09.724889743 +0100
+@@ -4648,7 +4648,7 @@
+       void (*remove_sta_debugfs)(void *priv, void *priv_sta);
+       u32 (*get_expected_throughput)(void *priv_sta);
+-};
++} __do_const;
+ static inline int rate_supported(struct ieee80211_sta *sta,
+                                enum ieee80211_band band,
+diff -Naur backports-3.18.1-1.org/include/trace/events/fs.h backports-3.18.1-1/include/trace/events/fs.h
+--- backports-3.18.1-1.org/include/trace/events/fs.h   1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/include/trace/events/fs.h       2014-12-28 14:10:09.728889769 +0100
+@@ -0,0 +1,53 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM fs
++
++#if !defined(_TRACE_FS_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_FS_H
++
++#include <linux/fs.h>
++#include <linux/tracepoint.h>
++
++TRACE_EVENT(do_sys_open,
++
++      TP_PROTO(const char *filename, int flags, int mode),
++
++      TP_ARGS(filename, flags, mode),
++
++      TP_STRUCT__entry(
++              __string(       filename, filename              )
++              __field(        int, flags                      )
++              __field(        int, mode                       )
++      ),
++
++      TP_fast_assign(
++              __assign_str(filename, filename);
++              __entry->flags = flags;
++              __entry->mode = mode;
++      ),
++
++      TP_printk("\"%s\" %x %o",
++                __get_str(filename), __entry->flags, __entry->mode)
++);
++
++TRACE_EVENT(open_exec,
++
++      TP_PROTO(const char *filename),
++
++      TP_ARGS(filename),
++
++      TP_STRUCT__entry(
++              __string(       filename, filename              )
++      ),
++
++      TP_fast_assign(
++              __assign_str(filename, filename);
++      ),
++
++      TP_printk("\"%s\"",
++                __get_str(filename))
++);
++
++#endif /* _TRACE_FS_H */
++
++/* This part must be outside protection */
++#include <trace/define_trace.h>
+diff -Naur backports-3.18.1-1.org/net/bluetooth/6lowpan.c backports-3.18.1-1/net/bluetooth/6lowpan.c
+--- backports-3.18.1-1.org/net/bluetooth/6lowpan.c     2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/bluetooth/6lowpan.c 2014-12-28 14:10:09.784890034 +0100
+@@ -367,7 +367,6 @@
+ drop:
+       dev->stats.rx_dropped++;
+-      kfree_skb(skb);
+       return NET_RX_DROP;
+ }
+diff -Naur backports-3.18.1-1.org/net/bluetooth/bnep/core.c backports-3.18.1-1/net/bluetooth/bnep/core.c
+--- backports-3.18.1-1.org/net/bluetooth/bnep/core.c   2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/bluetooth/bnep/core.c       2014-12-28 14:10:09.784890034 +0100
+@@ -533,6 +533,9 @@
+       BT_DBG("");
++      if (!l2cap_is_socket(sock))
++              return -EBADFD;
++
+       baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst);
+       baswap((void *) src, &l2cap_pi(sock->sk)->chan->src);
+diff -Naur backports-3.18.1-1.org/net/bluetooth/cmtp/core.c backports-3.18.1-1/net/bluetooth/cmtp/core.c
+--- backports-3.18.1-1.org/net/bluetooth/cmtp/core.c   2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/bluetooth/cmtp/core.c       2014-12-28 14:10:09.784890034 +0100
+@@ -334,6 +334,9 @@
+       BT_DBG("");
++      if (!l2cap_is_socket(sock))
++              return -EBADFD;
++
+       session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL);
+       if (!session)
+               return -ENOMEM;
+diff -Naur backports-3.18.1-1.org/net/bluetooth/hci_sock.c backports-3.18.1-1/net/bluetooth/hci_sock.c
+--- backports-3.18.1-1.org/net/bluetooth/hci_sock.c    2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/bluetooth/hci_sock.c        2014-12-28 14:10:09.784890034 +0100
+@@ -1067,7 +1067,7 @@
+                       uf.event_mask[1] = *((u32 *) f->event_mask + 1);
+               }
+-              len = min_t(unsigned int, len, sizeof(uf));
++              len = min((size_t)len, sizeof(uf));
+               if (copy_from_user(&uf, optval, len)) {
+                       err = -EFAULT;
+                       break;
+diff -Naur backports-3.18.1-1.org/net/bluetooth/hidp/core.c backports-3.18.1-1/net/bluetooth/hidp/core.c
+--- backports-3.18.1-1.org/net/bluetooth/hidp/core.c   2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/bluetooth/hidp/core.c       2014-12-28 14:10:09.784890034 +0100
+@@ -1322,13 +1322,14 @@
+ {
+       struct hidp_session *session;
+       struct l2cap_conn *conn;
+-      struct l2cap_chan *chan = l2cap_pi(ctrl_sock->sk)->chan;
++      struct l2cap_chan *chan;
+       int ret;
+       ret = hidp_verify_sockets(ctrl_sock, intr_sock);
+       if (ret)
+               return ret;
++      chan = l2cap_pi(ctrl_sock->sk)->chan;
+       conn = NULL;
+       l2cap_chan_lock(chan);
+       if (chan->conn)
+diff -Naur backports-3.18.1-1.org/net/bluetooth/l2cap_core.c backports-3.18.1-1/net/bluetooth/l2cap_core.c
+--- backports-3.18.1-1.org/net/bluetooth/l2cap_core.c  2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/bluetooth/l2cap_core.c      2014-12-28 14:10:09.784890034 +0100
+@@ -3512,8 +3512,10 @@
+                       break;
+               case L2CAP_CONF_RFC:
+-                      if (olen == sizeof(rfc))
+-                              memcpy(&rfc, (void *)val, olen);
++                      if (olen != sizeof(rfc))
++                              break;
++
++                      memcpy(&rfc, (void *)val, olen);
+                       if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
+                           rfc.mode != chan->mode)
+diff -Naur backports-3.18.1-1.org/net/bluetooth/l2cap_sock.c backports-3.18.1-1/net/bluetooth/l2cap_sock.c
+--- backports-3.18.1-1.org/net/bluetooth/l2cap_sock.c  2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/bluetooth/l2cap_sock.c      2014-12-28 14:10:09.788890064 +0100
+@@ -628,7 +628,8 @@
+       struct sock *sk = sock->sk;
+       struct l2cap_chan *chan = l2cap_pi(sk)->chan;
+       struct l2cap_options opts;
+-      int len, err = 0;
++      int err = 0;
++      size_t len = optlen;
+       u32 opt;
+       BT_DBG("sk %p", sk);
+@@ -655,7 +656,7 @@
+               opts.max_tx   = chan->max_tx;
+               opts.txwin_size = chan->tx_win;
+-              len = min_t(unsigned int, sizeof(opts), optlen);
++              len = min(sizeof(opts), len);
+               if (copy_from_user((char *) &opts, optval, len)) {
+                       err = -EFAULT;
+                       break;
+@@ -742,7 +743,8 @@
+       struct bt_security sec;
+       struct bt_power pwr;
+       struct l2cap_conn *conn;
+-      int len, err = 0;
++      int err = 0;
++      size_t len = optlen;
+       u32 opt;
+       BT_DBG("sk %p", sk);
+@@ -766,7 +768,7 @@
+               sec.level = BT_SECURITY_LOW;
+-              len = min_t(unsigned int, sizeof(sec), optlen);
++              len = min(sizeof(sec), len);
+               if (copy_from_user((char *) &sec, optval, len)) {
+                       err = -EFAULT;
+                       break;
+@@ -862,7 +864,7 @@
+               pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
+-              len = min_t(unsigned int, sizeof(pwr), optlen);
++              len = min(sizeof(pwr), len);
+               if (copy_from_user((char *) &pwr, optval, len)) {
+                       err = -EFAULT;
+                       break;
+diff -Naur backports-3.18.1-1.org/net/bluetooth/rfcomm/sock.c backports-3.18.1-1/net/bluetooth/rfcomm/sock.c
+--- backports-3.18.1-1.org/net/bluetooth/rfcomm/sock.c 2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/bluetooth/rfcomm/sock.c     2014-12-28 14:10:09.788890064 +0100
+@@ -695,7 +695,7 @@
+       struct sock *sk = sock->sk;
+       struct bt_security sec;
+       int err = 0;
+-      size_t len;
++      size_t len = optlen;
+       u32 opt;
+       BT_DBG("sk %p", sk);
+@@ -717,7 +717,7 @@
+               sec.level = BT_SECURITY_LOW;
+-              len = min_t(unsigned int, sizeof(sec), optlen);
++              len = min(sizeof(sec), len);
+               if (copy_from_user((char *) &sec, optval, len)) {
+                       err = -EFAULT;
+                       break;
+diff -Naur backports-3.18.1-1.org/net/bluetooth/rfcomm/tty.c backports-3.18.1-1/net/bluetooth/rfcomm/tty.c
+--- backports-3.18.1-1.org/net/bluetooth/rfcomm/tty.c  2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/bluetooth/rfcomm/tty.c      2014-12-28 14:10:09.788890064 +0100
+@@ -752,7 +752,7 @@
+       BT_DBG("tty %p id %d", tty, tty->index);
+       BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst,
+-             dev->channel, dev->port.count);
++             dev->channel, atomic_read(&dev->port.count));
+       err = tty_port_open(&dev->port, tty, filp);
+       if (err)
+@@ -775,7 +775,7 @@
+       struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
+       BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
+-                                              dev->port.count);
++                                              atomic_read(&dev->port.count));
+       tty_port_close(&dev->port, tty, filp);
+ }
+diff -Naur backports-3.18.1-1.org/net/ieee802154/6lowpan_rtnl.c backports-3.18.1-1/net/ieee802154/6lowpan_rtnl.c
+--- backports-3.18.1-1.org/net/ieee802154/6lowpan_rtnl.c       2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/ieee802154/6lowpan_rtnl.c   2014-12-28 14:10:09.796890100 +0100
+@@ -639,7 +639,7 @@
+       dev_put(real_dev);
+ }
+-static struct rtnl_link_ops lowpan_link_ops __read_mostly = {
++static struct rtnl_link_ops lowpan_link_ops = {
+       .kind           = "lowpan",
+       .priv_size      = sizeof(struct lowpan_dev_info),
+       .setup          = lowpan_setup,
+diff -Naur backports-3.18.1-1.org/net/ieee802154/reassembly.c backports-3.18.1-1/net/ieee802154/reassembly.c
+--- backports-3.18.1-1.org/net/ieee802154/reassembly.c 2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/ieee802154/reassembly.c     2014-12-28 14:10:09.796890100 +0100
+@@ -460,14 +460,13 @@
+ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
+ {
+-      struct ctl_table *table;
++      ctl_table_no_const *table = NULL;
+       struct ctl_table_header *hdr;
+       struct netns_ieee802154_lowpan *ieee802154_lowpan =
+               net_ieee802154_lowpan(net);
+-      table = lowpan_frags_ns_ctl_table;
+       if (!net_eq(net, &init_net)) {
+-              table = kmemdup(table, sizeof(lowpan_frags_ns_ctl_table),
++              table = kmemdup(lowpan_frags_ns_ctl_table, sizeof(lowpan_frags_ns_ctl_table),
+                               GFP_KERNEL);
+               if (table == NULL)
+                       goto err_alloc;
+@@ -494,8 +493,7 @@
+       return 0;
+ err_reg:
+-      if (!net_eq(net, &init_net))
+-              kfree(table);
++      kfree(table);
+ err_alloc:
+       return -ENOMEM;
+ }
+diff -Naur backports-3.18.1-1.org/net/mac80211/cfg.c backports-3.18.1-1/net/mac80211/cfg.c
+--- backports-3.18.1-1.org/net/mac80211/cfg.c  2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/mac80211/cfg.c      2014-12-28 14:10:09.812890175 +0100
+@@ -541,7 +541,7 @@
+                       ret = ieee80211_vif_use_channel(sdata, chandef,
+                                       IEEE80211_CHANCTX_EXCLUSIVE);
+               }
+-      } else if (local->open_count == local->monitors) {
++      } else if (local_read(&local->open_count) == local->monitors) {
+               local->_oper_chandef = *chandef;
+               ieee80211_hw_config(local, 0);
+       }
+@@ -3326,7 +3326,7 @@
+               else
+                       local->probe_req_reg--;
+-              if (!local->open_count)
++              if (!local_read(&local->open_count))
+                       break;
+               ieee80211_queue_work(&local->hw, &local->reconfig_filter);
+@@ -3460,8 +3460,8 @@
+       if (chanctx_conf) {
+               *chandef = sdata->vif.bss_conf.chandef;
+               ret = 0;
+-      } else if (local->open_count > 0 &&
+-                 local->open_count == local->monitors &&
++      } else if (local_read(&local->open_count) > 0 &&
++                 local_read(&local->open_count) == local->monitors &&
+                  sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+               if (local->use_chanctx)
+                       *chandef = local->monitor_chandef;
+diff -Naur backports-3.18.1-1.org/net/mac80211/ieee80211_i.h backports-3.18.1-1/net/mac80211/ieee80211_i.h
+--- backports-3.18.1-1.org/net/mac80211/ieee80211_i.h  2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/mac80211/ieee80211_i.h      2014-12-28 14:10:09.812890175 +0100
+@@ -29,6 +29,7 @@
+ #include <net/ieee80211_radiotap.h>
+ #include <net/cfg80211.h>
+ #include <net/mac80211.h>
++#include <asm/local.h>
+ #include "key.h"
+ #include "sta_info.h"
+ #include "debug.h"
+@@ -1057,7 +1058,7 @@
+       /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
+       spinlock_t queue_stop_reason_lock;
+-      int open_count;
++      local_t open_count;
+       int monitors, cooked_mntrs;
+       /* number of interfaces with corresponding FIF_ flags */
+       int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
+diff -Naur backports-3.18.1-1.org/net/mac80211/iface.c backports-3.18.1-1/net/mac80211/iface.c
+--- backports-3.18.1-1.org/net/mac80211/iface.c        2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/mac80211/iface.c    2014-12-28 14:10:09.812890175 +0100
+@@ -532,7 +532,7 @@
+               break;
+       }
+-      if (local->open_count == 0) {
++      if (local_read(&local->open_count) == 0) {
+               res = drv_start(local);
+               if (res)
+                       goto err_del_bss;
+@@ -579,7 +579,7 @@
+                       res = drv_add_interface(local, sdata);
+                       if (res)
+                               goto err_stop;
+-              } else if (local->monitors == 0 && local->open_count == 0) {
++              } else if (local->monitors == 0 && local_read(&local->open_count) == 0) {
+                       res = ieee80211_add_virtual_monitor(local);
+                       if (res)
+                               goto err_stop;
+@@ -688,7 +688,7 @@
+               atomic_inc(&local->iff_promiscs);
+       if (coming_up)
+-              local->open_count++;
++              local_inc(&local->open_count);
+       if (hw_reconf_flags)
+               ieee80211_hw_config(local, hw_reconf_flags);
+@@ -726,7 +726,7 @@
+  err_del_interface:
+       drv_remove_interface(local, sdata);
+  err_stop:
+-      if (!local->open_count)
++      if (!local_read(&local->open_count))
+               drv_stop(local);
+  err_del_bss:
+       sdata->bss = NULL;
+@@ -892,7 +892,7 @@
+       }
+       if (going_down)
+-              local->open_count--;
++              local_dec(&local->open_count);
+       switch (sdata->vif.type) {
+       case NL80211_IFTYPE_AP_VLAN:
+@@ -954,7 +954,7 @@
+       }
+       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+-      if (local->open_count == 0)
++      if (local_read(&local->open_count) == 0)
+               ieee80211_clear_tx_pending(local);
+       /*
+@@ -997,7 +997,7 @@
+       if (cancel_scan)
+               flush_delayed_work(&local->scan_work);
+-      if (local->open_count == 0) {
++      if (local_read(&local->open_count) == 0) {
+               ieee80211_stop_device(local);
+               /* no reconfiguring after stop! */
+@@ -1008,7 +1008,7 @@
+       ieee80211_configure_filter(local);
+       ieee80211_hw_config(local, hw_reconf_flags);
+-      if (local->monitors == local->open_count)
++      if (local->monitors == local_read(&local->open_count))
+               ieee80211_add_virtual_monitor(local);
+ }
+diff -Naur backports-3.18.1-1.org/net/mac80211/main.c backports-3.18.1-1/net/mac80211/main.c
+--- backports-3.18.1-1.org/net/mac80211/main.c 2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/mac80211/main.c     2014-12-28 14:10:09.812890175 +0100
+@@ -175,7 +175,7 @@
+               changed &= ~(IEEE80211_CONF_CHANGE_CHANNEL |
+                            IEEE80211_CONF_CHANGE_POWER);
+-      if (changed && local->open_count) {
++      if (changed && local_read(&local->open_count)) {
+               ret = drv_config(local, changed);
+               /*
+                * Goal:
+diff -Naur backports-3.18.1-1.org/net/mac80211/pm.c backports-3.18.1-1/net/mac80211/pm.c
+--- backports-3.18.1-1.org/net/mac80211/pm.c   2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/mac80211/pm.c       2014-12-28 14:10:09.812890175 +0100
+@@ -12,7 +12,7 @@
+       struct ieee80211_sub_if_data *sdata;
+       struct sta_info *sta;
+-      if (!local->open_count)
++      if (!local_read(&local->open_count))
+               goto suspend;
+       ieee80211_scan_cancel(local);
+@@ -59,7 +59,7 @@
+       cancel_work_sync(&local->dynamic_ps_enable_work);
+       del_timer_sync(&local->dynamic_ps_timer);
+-      local->wowlan = wowlan && local->open_count;
++      local->wowlan = wowlan && local_read(&local->open_count);
+       if (local->wowlan) {
+               int err = drv_suspend(local, wowlan);
+               if (err < 0) {
+@@ -125,7 +125,7 @@
+       WARN_ON(!list_empty(&local->chanctx_list));
+       /* stop hardware - this must stop RX */
+-      if (local->open_count)
++      if (local_read(&local->open_count))
+               ieee80211_stop_device(local);
+  suspend:
+diff -Naur backports-3.18.1-1.org/net/mac80211/rate.c backports-3.18.1-1/net/mac80211/rate.c
+--- backports-3.18.1-1.org/net/mac80211/rate.c 2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/mac80211/rate.c     2014-12-28 14:10:09.812890175 +0100
+@@ -720,7 +720,7 @@
+       ASSERT_RTNL();
+-      if (local->open_count)
++      if (local_read(&local->open_count))
+               return -EBUSY;
+       if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) {
+diff -Naur backports-3.18.1-1.org/net/mac80211/util.c backports-3.18.1-1/net/mac80211/util.c
+--- backports-3.18.1-1.org/net/mac80211/util.c 2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/mac80211/util.c     2014-12-28 14:10:09.816890209 +0100
+@@ -1669,7 +1669,7 @@
+       }
+ #endif
+       /* everything else happens only if HW was up & running */
+-      if (!local->open_count)
++      if (!local_read(&local->open_count))
+               goto wake_up;
+       /*
+@@ -1895,7 +1895,7 @@
+       local->in_reconfig = false;
+       barrier();
+-      if (local->monitors == local->open_count && local->monitors > 0)
++      if (local->monitors == local_read(&local->open_count) && local->monitors > 0)
+               ieee80211_add_virtual_monitor(local);
+       /*
+diff -Naur backports-3.18.1-1.org/net/wireless/wext-core.c backports-3.18.1-1/net/wireless/wext-core.c
+--- backports-3.18.1-1.org/net/wireless/wext-core.c    2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/net/wireless/wext-core.c        2014-12-28 14:10:09.832890290 +0100
+@@ -748,8 +748,7 @@
+                */
+               /* Support for very large requests */
+-              if ((descr->flags & IW_DESCR_FLAG_NOMAX) &&
+-                  (user_length > descr->max_tokens)) {
++              if (user_length > descr->max_tokens) {
+                       /* Allow userspace to GET more than max so
+                        * we can support any size GET requests.
+                        * There is still a limit : -ENOMEM.
+@@ -788,22 +787,6 @@
+               }
+       }
+-      if (IW_IS_GET(cmd) && !(descr->flags & IW_DESCR_FLAG_NOMAX)) {
+-              /*
+-               * If this is a GET, but not NOMAX, it means that the extra
+-               * data is not bounded by userspace, but by max_tokens. Thus
+-               * set the length to max_tokens. This matches the extra data
+-               * allocation.
+-               * The driver should fill it with the number of tokens it
+-               * provided, and it may check iwp->length rather than having
+-               * knowledge of max_tokens. If the driver doesn't change the
+-               * iwp->length, this ioctl just copies back max_token tokens
+-               * filled with zeroes. Hopefully the driver isn't claiming
+-               * them to be valid data.
+-               */
+-              iwp->length = descr->max_tokens;
+-      }
+-
+       err = handler(dev, info, (union iwreq_data *) iwp, extra);
+       iwp->length += essid_compat;
diff --git a/src/patches/backports-3.18.1-1-ipfire-build.patch b/src/patches/backports-3.18.1-1-ipfire-build.patch
new file mode 100644 (file)
index 0000000..0b2998e
--- /dev/null
@@ -0,0 +1,34 @@
+diff -Naur backports-3.18.1-1.org/Makefile backports-3.18.1-1/Makefile
+--- backports-3.18.1-1.org/Makefile    2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/Makefile        2014-12-29 15:51:19.358111370 +0100
+@@ -8,9 +8,9 @@
+ SHELL := /bin/bash
+ BACKPORT_PWD := $(shell pwd)
+-KMODDIR ?= updates
++KMODDIR ?= kernel
+ ifneq ($(origin KLIB), undefined)
+-KMODPATH_ARG := "INSTALL_MOD_PATH=$(KLIB)"
++KMODPATH_ARG :=
+ else
+ KLIB := /lib/modules/$(shell uname -r)/
+ KMODPATH_ARG :=
+diff -Naur backports-3.18.1-1.org/Makefile.real backports-3.18.1-1/Makefile.real
+--- backports-3.18.1-1.org/Makefile.real       2014-12-21 22:37:13.000000000 +0100
++++ backports-3.18.1-1/Makefile.real   2014-12-29 15:51:40.934780933 +0100
+@@ -92,11 +92,11 @@
+       @$(MAKE) -C $(KLIB_BUILD) M=$(BACKPORT_PWD)                     \
+               INSTALL_MOD_DIR=$(KMODDIR) $(KMODPATH_ARG)              \
+               modules_install
+-      @./scripts/blacklist.sh $(KLIB)/ $(KLIB)/$(KMODDIR)
++#     @./scripts/blacklist.sh $(KLIB)/ $(KLIB)/$(KMODDIR)
+       @./scripts/compress_modules.sh $(KLIB)/$(KMODDIR)
+-      @./scripts/check_depmod.sh
+-      @/sbin/depmod -a
+-      @./scripts/update-initramfs.sh $(KLIB)
++#     @./scripts/check_depmod.sh
++#     @/sbin/depmod -a
++#     @./scripts/update-initramfs.sh $(KLIB)
+       @echo
+       @echo Your backported driver modules should be installed now.
+       @echo Reboot.
diff --git a/src/patches/backports-3.18.1-1_add_libertas_uap.patch b/src/patches/backports-3.18.1-1_add_libertas_uap.patch
new file mode 100644 (file)
index 0000000..9a5b01b
--- /dev/null
@@ -0,0 +1,5058 @@
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/Kconfig backports-3.18.1-1/drivers/net/wireless/Kconfig
+--- backports-3.18.1-1.org/drivers/net/wireless/Kconfig        2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/Kconfig    2014-12-29 20:37:43.945764119 +0100
+@@ -55,6 +55,14 @@
+       ---help---
+         A driver for Marvell Libertas 8388 USB devices using thinfirm.
++config LIBERTAS_UAP
++      tristate "Marvell 8xxx Libertas UAP"
++      depends on MAC80211
++      depends on MMC
++      select FW_LOADER
++      ---help---
++        Driver for Marvell Libertas 8xxx micro AP.
++
+ config AIRO
+       depends on n
+       tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/Makefile backports-3.18.1-1/drivers/net/wireless/libertas_uap/Makefile
+--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/Makefile  1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/Makefile      2014-12-29 20:41:50.975778546 +0100
+@@ -0,0 +1,6 @@
++obj-$(CPTCFG_LIBERTAS_UAP) += uap8xxx.o
++
++uap8xxx-y += uap_main.o uap_sdio_mmc.o
++uap8xxx-$(CPTCFG_PROC_FS) += uap_proc.o uap_debug.o
++
++EXTRA_CFLAGS += -DFPNUM='"52"' -DPXA3XX_DMA_ALIGN -DDEBUG_LEVEL1
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_debug.c backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_debug.c
+--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_debug.c       1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_debug.c   2014-12-29 20:37:43.949097590 +0100
+@@ -0,0 +1,260 @@
++/** @file uap_debug.c
++  * @brief This file contains functions for debug proc file.
++  *
++  * Copyright (C) 2008-2009, Marvell International Ltd.
++  *
++  * This software file (the "File") is distributed by Marvell International
++  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
++  * (the "License").  You may use, redistribute and/or modify this File in
++  * accordance with the terms and conditions of the License, a copy of which
++  * is available along with the File in the gpl.txt file or by writing to
++  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
++  *
++  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
++  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
++  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
++  * this warranty disclaimer.
++  *
++  */
++#ifdef CONFIG_PROC_FS
++#include  "uap_headers.h"
++
++/********************************************************
++              Local Variables
++********************************************************/
++
++#define item_size(n) (sizeof ((uap_adapter *)0)->n)
++#define item_addr(n) ((u32) &((uap_adapter *)0)->n)
++
++#define item_dbg_size(n) (sizeof (((uap_adapter *)0)->dbg.n))
++#define item_dbg_addr(n) ((u32) &(((uap_adapter *)0)->dbg.n))
++
++#define item_dev_size(n) (sizeof ((uap_dev_t *)0)->n)
++#define item_dev_addr(n) ((u32) &((uap_dev_t *)0)->n)
++
++/** MicroAp device offset */
++#define OFFSET_UAP_DEV                0x01
++/** Bluetooth adapter offset */
++#define OFFSET_UAP_ADAPTER    0x02
++
++struct debug_data
++{
++    /** Name */
++    char name[32];
++    /** Size */
++    u32 size;
++    /** Address */
++    u32 addr;
++    /** Offset */
++    u32 offset;
++    /** Flag */
++    u32 flag;
++};
++
++/* To debug any member of uap_adapter, simply add one line here.
++ */
++static struct debug_data items[] = {
++    {"cmd_sent", item_dev_size(cmd_sent), 0, item_dev_addr(cmd_sent),
++     OFFSET_UAP_DEV},
++    {"data_sent", item_dev_size(data_sent), 0, item_dev_addr(data_sent),
++     OFFSET_UAP_DEV},
++    {"IntCounter", item_size(IntCounter), 0, item_addr(IntCounter),
++     OFFSET_UAP_ADAPTER},
++    {"cmd_pending", item_size(cmd_pending), 0, item_addr(cmd_pending),
++     OFFSET_UAP_ADAPTER},
++    {"num_cmd_h2c_fail", item_dbg_size(num_cmd_host_to_card_failure), 0,
++     item_dbg_addr(num_cmd_host_to_card_failure), OFFSET_UAP_ADAPTER},
++    {"num_tx_h2c_fail", item_dbg_size(num_tx_host_to_card_failure), 0,
++     item_dbg_addr(num_tx_host_to_card_failure), OFFSET_UAP_ADAPTER},
++    {"psmode", item_size(psmode), 0, item_addr(psmode), OFFSET_UAP_ADAPTER},
++    {"ps_state", item_size(ps_state), 0, item_addr(ps_state),
++     OFFSET_UAP_ADAPTER},
++#ifdef DEBUG_LEVEL1
++    {"drvdbg", sizeof(drvdbg), (u32) & drvdbg, 0, 0}
++#endif
++};
++
++static int num_of_items = sizeof(items) / sizeof(items[0]);
++
++/********************************************************
++              Global Variables
++********************************************************/
++
++/********************************************************
++              Local Functions
++********************************************************/
++/**
++ *  @brief proc read function
++ *
++ *  @param page          pointer to buffer
++ *  @param s       read data starting position
++ *  @param off     offset
++ *  @param cnt     counter
++ *  @param eof     end of file flag
++ *  @param data    data to output
++ *  @return      number of output data
++ */
++static int uap_debug_proc_show(struct seq_file *s, void *data) {
++    int val = 0;
++    int i;
++
++    struct debug_data *d = (struct debug_data *)s->private;
++
++    if (MODULE_GET == 0)
++        return UAP_STATUS_FAILURE;
++
++    for (i = 0; i < num_of_items; i++) {
++        if (d[i].size == 1)
++            val = *((u8 *) d[i].addr);
++        else if (d[i].size == 2)
++            val = *((u16 *) d[i].addr);
++        else if (d[i].size == 4)
++            val = *((u32 *) d[i].addr);
++
++        seq_printf(s, "%s=%d\n", d[i].name, val);
++    }
++    MODULE_PUT;
++    return 0;
++}
++
++static int uap_debug_proc_open(struct inode* inode, struct file* file) {
++      return single_open(file, uap_debug_proc_show, PDE_DATA(inode));
++}
++
++/**
++ *  @brief proc write function
++ *
++ *  @param f     file pointer
++ *  @param buf     pointer to data buffer
++ *  @param cnt     data number to write
++ *  @param data    data to write
++ *  @return      number of data
++ */
++static ssize_t uap_debug_proc_write(struct file *f, const char __user *buf, size_t cnt, loff_t *data) {
++    int r, i;
++    char *pdata;
++    char *p;
++    char *p0;
++    char *p1;
++    char *p2;
++    struct debug_data *d = (struct debug_data *)PDE_DATA(file_inode(f));
++
++    if (MODULE_GET == 0)
++        return UAP_STATUS_FAILURE;
++
++    pdata = (char *) kmalloc(cnt, GFP_KERNEL);
++    if (pdata == NULL) {
++        MODULE_PUT;
++        return 0;
++    }
++
++    if (copy_from_user(pdata, buf, cnt)) {
++        PRINTM(INFO, "Copy from user failed\n");
++        kfree(pdata);
++        MODULE_PUT;
++        return 0;
++    }
++
++    p0 = pdata;
++    for (i = 0; i < num_of_items; i++) {
++        do {
++            p = strstr(p0, d[i].name);
++            if (p == NULL)
++                break;
++            p1 = strchr(p, '\n');
++            if (p1 == NULL)
++                break;
++            p0 = p1++;
++            p2 = strchr(p, '=');
++            if (!p2)
++                break;
++            p2++;
++            r = string_to_number(p2);
++            if (d[i].size == 1)
++                *((u8 *) d[i].addr) = (u8) r;
++            else if (d[i].size == 2)
++                *((u16 *) d[i].addr) = (u16) r;
++            else if (d[i].size == 4)
++                *((u32 *) d[i].addr) = (u32) r;
++            break;
++        } while (TRUE);
++    }
++    kfree(pdata);
++#ifdef DEBUG_LEVEL1
++    printk(KERN_ALERT "drvdbg = 0x%x\n", drvdbg);
++    printk(KERN_ALERT "INFO  (%08lx) %s\n", DBG_INFO,
++           (drvdbg & DBG_INFO) ? "X" : "");
++    printk(KERN_ALERT "WARN  (%08lx) %s\n", DBG_WARN,
++           (drvdbg & DBG_WARN) ? "X" : "");
++    printk(KERN_ALERT "ENTRY (%08lx) %s\n", DBG_ENTRY,
++           (drvdbg & DBG_ENTRY) ? "X" : "");
++    printk(KERN_ALERT "CMD_D (%08lx) %s\n", DBG_CMD_D,
++           (drvdbg & DBG_CMD_D) ? "X" : "");
++    printk(KERN_ALERT "DAT_D (%08lx) %s\n", DBG_DAT_D,
++           (drvdbg & DBG_DAT_D) ? "X" : "");
++    printk(KERN_ALERT "CMND  (%08lx) %s\n", DBG_CMND,
++           (drvdbg & DBG_CMND) ? "X" : "");
++    printk(KERN_ALERT "DATA  (%08lx) %s\n", DBG_DATA,
++           (drvdbg & DBG_DATA) ? "X" : "");
++    printk(KERN_ALERT "ERROR (%08lx) %s\n", DBG_ERROR,
++           (drvdbg & DBG_ERROR) ? "X" : "");
++    printk(KERN_ALERT "FATAL (%08lx) %s\n", DBG_FATAL,
++           (drvdbg & DBG_FATAL) ? "X" : "");
++    printk(KERN_ALERT "MSG   (%08lx) %s\n", DBG_MSG,
++           (drvdbg & DBG_MSG) ? "X" : "");
++#endif
++    MODULE_PUT;
++    return cnt;
++}
++
++static const struct file_operations uap_debug_proc_fops = {
++      .owner   = THIS_MODULE,
++      .open    = uap_debug_proc_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = single_release,
++      .write   = uap_debug_proc_write,
++};
++
++/********************************************************
++              Global Functions
++********************************************************/
++/**
++ *  @brief create debug proc file
++ *
++ *  @param priv          pointer uap_private
++ *  @param dev     pointer net_device
++ *  @return      N/A
++ */
++void
++uap_debug_entry(uap_private * priv, struct net_device *dev)
++{
++    int i;
++
++    if (priv->proc_entry == NULL)
++        return;
++
++    for (i = 0; i < num_of_items; i++) {
++        if (items[i].flag & OFFSET_UAP_ADAPTER)
++            items[i].addr = items[i].offset + (u32) priv->adapter;
++        if (items[i].flag & OFFSET_UAP_DEV)
++            items[i].addr = items[i].offset + (u32) & priv->uap_dev;
++    }
++    proc_create_data("debug", 0644, priv->proc_entry, &uap_debug_proc_fops,
++      &items[0]);
++}
++
++/**
++ *  @brief remove proc file
++ *
++ *  @param priv          pointer uap_private
++ *  @return      N/A
++ */
++void
++uap_debug_remove(uap_private * priv)
++{
++    remove_proc_entry("debug", priv->proc_entry);
++}
++
++#endif
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_drv.h backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_drv.h
+--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_drv.h 1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_drv.h     2014-12-29 20:37:43.949097590 +0100
+@@ -0,0 +1,667 @@
++/** @file uap_drv.h
++  * @brief This file contains Linux OS related definitions and
++  * declarations, uAP driver
++  *
++  * Copyright (C) 2008-2009, Marvell International Ltd.
++  *
++  * This software file (the "File") is distributed by Marvell International
++  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
++  * (the "License").  You may use, redistribute and/or modify this File in
++  * accordance with the terms and conditions of the License, a copy of which
++  * is available along with the File in the gpl.txt file or by writing to
++  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
++  *
++  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
++  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
++  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
++  * this warranty disclaimer.
++  *
++  */
++
++#ifndef _UAP_DRV_H
++#define _UAP_DRV_H
++
++/** Driver release version */
++#define DRIVER_VERSION                "26146"
++
++/** True */
++#ifndef       TRUE
++#define TRUE                  1
++#endif
++/** False */
++#ifndef       FALSE
++#define       FALSE                   0
++#endif
++
++/** Bit definitions */
++#ifndef BIT
++#define BIT(x)        (1UL << (x))
++#endif
++
++/** Dma addresses are 32-bits wide.  */
++#ifndef __ATTRIB_ALIGN__
++#define __ATTRIB_ALIGN__ __attribute__((aligned(4)))
++#endif
++
++/**  attribute pack */
++#ifndef __ATTRIB_PACK__
++#define __ATTRIB_PACK__ __attribute__ ((packed))
++#endif
++
++/** Debug Macro definition*/
++#ifdef        DEBUG_LEVEL1
++
++extern u32 drvdbg;
++
++/** Debug message control bit definition for drvdbg */
++/** Debug message */
++#define       DBG_MSG         BIT(0)
++/** Debug fatal message */
++#define DBG_FATAL     BIT(1)
++/** Debug error message */
++#define DBG_ERROR     BIT(2)
++/** Debug data message */
++#define DBG_DATA      BIT(3)
++/** Debug command message */
++#define DBG_CMND      BIT(4)
++
++/** Debug data */
++#define DBG_DAT_D     BIT(16)
++/** Debug command */
++#define DBG_CMD_D     BIT(17)
++
++/** Debug entry */
++#define DBG_ENTRY     BIT(28)
++/** Debug warning */
++#define DBG_WARN      BIT(29)
++/** Debug info */
++#define DBG_INFO      BIT(30)
++
++/** Print info */
++#define       PRINTM_INFO(msg...)  {if (drvdbg & DBG_INFO) printk(KERN_DEBUG msg);}
++/** Print warn message */
++#define       PRINTM_WARN(msg...)  {if (drvdbg & DBG_WARN) printk(KERN_DEBUG msg);}
++/** Print entry */
++#define       PRINTM_ENTRY(msg...) {if (drvdbg & DBG_ENTRY) printk(KERN_DEBUG msg);}
++/** Print cmd_d */
++#define       PRINTM_CMD_D(msg...) {if (drvdbg & DBG_CMD_D) printk(KERN_DEBUG msg);}
++/** Print data_d */
++#define       PRINTM_DAT_D(msg...) {if (drvdbg & DBG_DAT_D) printk(KERN_DEBUG msg);}
++/** Print command */
++#define       PRINTM_CMND(msg...)  {if (drvdbg & DBG_CMND) printk(KERN_DEBUG msg);}
++/** Print data */
++#define       PRINTM_DATA(msg...)  {if (drvdbg & DBG_DATA) printk(KERN_DEBUG msg);}
++/** Print error message */
++#define       PRINTM_ERROR(msg...) {if (drvdbg & DBG_ERROR) printk(KERN_DEBUG msg);}
++/** Print fatal message */
++#define       PRINTM_FATAL(msg...) {if (drvdbg & DBG_FATAL) printk(KERN_DEBUG msg);}
++/** Print message */
++#define       PRINTM_MSG(msg...)   {if (drvdbg & DBG_MSG) printk(KERN_ALERT msg);}
++/** Print level */
++#define       PRINTM(level,msg...) PRINTM_##level(msg)
++
++#else
++
++#define       PRINTM(level,msg...) do {} while (0)
++
++#endif /* DEBUG_LEVEL1 */
++
++/** Wait until a condition becomes true */
++#define ASSERT(cond)                                          \
++do {                                                          \
++      if (!(cond))                                            \
++              PRINTM(INFO, "ASSERT: %s, %s:%i\n",             \
++                     __FUNCTION__, __FILE__, __LINE__);       \
++} while(0)
++
++/** Log enrty point for debugging */
++#define       ENTER()                 PRINTM(ENTRY, "Enter: %s, %s:%i\n", __FUNCTION__, \
++                                                      __FILE__, __LINE__)
++/** Log exit point for debugging */
++#define       LEAVE()                 PRINTM(ENTRY, "Leave: %s, %s:%i\n", __FUNCTION__, \
++                                                      __FILE__, __LINE__)
++
++#ifdef        DEBUG_LEVEL1
++/** Dump buffer length */
++#define DBG_DUMP_BUF_LEN    64
++/** Maximum dump per line */
++#define MAX_DUMP_PER_LINE   16
++/** Data dump length */
++#define DATA_DUMP_LEN       32
++
++static inline void
++hexdump(char *prompt, u8 * buf, int len)
++{
++    int i;
++    char dbgdumpbuf[DBG_DUMP_BUF_LEN];
++    char *ptr = dbgdumpbuf;
++
++    printk(KERN_DEBUG "%s:\n", prompt);
++    for (i = 1; i <= len; i++) {
++        ptr += sprintf(ptr, "%02x ", *buf);
++        buf++;
++        if (i % MAX_DUMP_PER_LINE == 0) {
++            *ptr = 0;
++            printk(KERN_DEBUG "%s\n", dbgdumpbuf);
++            ptr = dbgdumpbuf;
++        }
++    }
++    if (len % MAX_DUMP_PER_LINE) {
++        *ptr = 0;
++        printk(KERN_DEBUG "%s\n", dbgdumpbuf);
++    }
++}
++
++/** Debug command */
++#define DBG_HEXDUMP_CMD_D(x,y,z)    {if (drvdbg & DBG_CMD_D) hexdump(x,y,z);}
++/** Debug data */
++#define DBG_HEXDUMP_DAT_D(x,y,z)    {if (drvdbg & DBG_DAT_D) hexdump(x,y,z);}
++/** Debug hexdump */
++#define       DBG_HEXDUMP(level,x,y,z)    DBG_HEXDUMP_##level(x,y,z)
++/** hexdump */
++#define HEXDUMP(x,y,z)              {if (drvdbg & DBG_INFO) hexdump(x,y,z);}
++#else
++/** Do nothing since debugging is not turned on */
++#define DBG_HEXDUMP(level,x,y,z)    do {} while (0)
++/** Do nothing since debugging is not turned on */
++#define HEXDUMP(x,y,z)              do {} while (0)
++#endif
++
++/**
++ * Typedefs
++ */
++/** Unsigned char */
++typedef u8 BOOLEAN;
++
++/*
++ * OS macro definitions
++ */
++/** OS macro to get time */
++#define os_time_get() jiffies
++
++/** OS macro to update transfer start time */
++#define UpdateTransStart(dev) { \
++      dev->trans_start = jiffies; \
++}
++
++/** Try to get a reference to the module */
++#define MODULE_GET    try_module_get(THIS_MODULE)
++/** Decrease module reference count */
++#define MODULE_PUT    module_put(THIS_MODULE)
++
++/** OS macro to initialize semaphore */
++#define OS_INIT_SEMAPHORE(x)  sema_init(x,1)
++/** OS macro to acquire blocking semaphore */
++#define OS_ACQ_SEMAPHORE_BLOCK(x)     down_interruptible(x)
++/** OS macro to acquire non-blocking semaphore */
++#define OS_ACQ_SEMAPHORE_NOBLOCK(x)   down_trylock(x)
++/** OS macro to release semaphore */
++#define OS_REL_SEMAPHORE(x)           up(x)
++
++static inline void
++os_sched_timeout(u32 millisec)
++{
++    set_current_state(TASK_INTERRUPTIBLE);
++    schedule_timeout((millisec * HZ) / 1000);
++}
++
++/** Maximum size of ethernet packet */
++#define MRVDRV_MAXIMUM_ETH_PACKET_SIZE        1514
++
++/** Maximum size of multicast list */
++#define MRVDRV_MAX_MULTICAST_LIST_SIZE        32
++
++/** Find minimum */
++#ifndef MIN
++#define MIN(a,b)              ((a) < (b) ? (a) : (b))
++#endif
++
++/** Find maximum */
++#ifndef MAX
++#define MAX(a,b)              ((a) > (b) ? (a) : (b))
++#endif
++
++/** Find number of elements */
++#ifndef NELEMENTS
++#define NELEMENTS(x) (sizeof(x)/sizeof(x[0]))
++#endif
++
++/** Buffer Constants */
++
++/** Size of command buffer */
++#define MRVDRV_SIZE_OF_CMD_BUFFER       (2 * 1024)
++
++/** Length of device length */
++#define DEV_NAME_LEN                  32
++
++/** Length of ethernet address */
++#ifndef       ETH_ALEN
++#define ETH_ALEN                      6
++#endif
++
++/** Default watchdog timeout */
++#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (2 * HZ)
++
++/** Success */
++#define UAP_STATUS_SUCCESS         (0)
++/** Failure */
++#define UAP_STATUS_FAILURE         (-1)
++/** Not accepted */
++#define UAP_STATUS_NOT_ACCEPTED    (-2)
++
++/** Max loop count (* 100ms) for waiting device ready at init time */
++#define MAX_WAIT_DEVICE_READY_COUNT   50
++
++/** Tx high watermark. Stop Tx queue after this is crossed */
++#define TX_HIGH_WATERMARK   4
++/** Tx low watermark. Restart Tx queue after this is crossed */
++#define TX_LOW_WATERMARK    2
++
++/** Netlink protocol number */
++#define NETLINK_MARVELL     (MAX_LINKS - 1)
++/** Netlink maximum payload size */
++#define NL_MAX_PAYLOAD      1024
++/** Netlink multicast group number */
++#define NL_MULTICAST_GROUP  1
++
++/** 20 seconds */
++#define MRVDRV_TIMER_20S              20000
++
++/** Host Command option for wait till Send */
++#define HostCmd_OPTION_WAITFORSEND            0x0001
++/** Host Command option for wait for RSP */
++#define HostCmd_OPTION_WAITFORRSP             0x0002
++/** Host Command option for wait for RSP or Timeout */
++#define HostCmd_OPTION_WAITFORRSP_TIMEOUT     0x0003
++/** Host Command option for wait for RSP of sleep confirm */
++#define HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM   0x0004
++
++/** Sleep until a condition gets true or a timeout elapses */
++#define os_wait_interruptible_timeout(waitq, cond, timeout) \
++      wait_event_interruptible_timeout(waitq, cond, ((timeout) * HZ / 1000))
++
++/** Private command ID to Host command */
++#define       UAPHOSTCMD                      (SIOCDEVPRIVATE + 1)
++
++/** Private command ID to Power Mode */
++#define       UAP_POWER_MODE                  (SIOCDEVPRIVATE + 3)
++/** sleep_param */
++typedef struct _ps_sleep_param
++{
++    /** control bitmap */
++    u32 ctrl_bitmap;
++    /** minimum sleep period (micro second) */
++    u32 min_sleep;
++    /** maximum sleep period (micro second) */
++    u32 max_sleep;
++} ps_sleep_param;
++
++/** inactivity sleep_param */
++typedef struct _inact_sleep_param
++{
++    /** inactivity timeout (micro second) */
++    u32 inactivity_to;
++    /** miniumu awake period (micro second) */
++    u32 min_awake;
++    /** maximum awake period (micro second) */
++    u32 max_awake;
++} inact_sleep_param;
++
++/** flag for ps mode */
++#define PS_FLAG_PS_MODE                 1
++/** flag for sleep param */
++#define PS_FLAG_SLEEP_PARAM             2
++/** flag for inactivity sleep param */
++#define PS_FLAG_INACT_SLEEP_PARAM       4
++
++/** Disable power mode */
++#define PS_MODE_DISABLE                      0
++/** Enable periodic dtim ps */
++#define PS_MODE_PERIODIC_DTIM                1
++/** Enable inactivity ps */
++#define PS_MODE_INACTIVITY                   2
++
++/** sleep parameter */
++#define SLEEP_PARAMETER                     1
++/** inactivity sleep parameter */
++#define INACTIVITY_SLEEP_PARAMETER          2
++/** ps_mgmt */
++typedef struct _ps_mgmt
++{
++    /** flags for valid field */
++    u16 flags;
++    /** power mode */
++    u16 ps_mode;
++    /** sleep param */
++    ps_sleep_param sleep_param;
++    /** inactivity sleep param */
++    inact_sleep_param inact_param;
++} ps_mgmt;
++
++/** Semaphore structure */
++typedef struct semaphore SEMAPHORE;
++
++/** Global Varibale Declaration */
++/** Private data structure of the device */
++typedef struct _uap_private uap_private;
++/** Adapter data structure of the device */
++typedef struct _uap_adapter uap_adapter;
++/** private structure */
++extern uap_private *uappriv;
++
++/** ENUM definition*/
++
++/** Hardware status codes */
++typedef enum _HARDWARE_STATUS
++{
++    HWReady,
++    HWInitializing,
++    HWReset,
++    HWClosing,
++    HWNotReady
++} HARDWARE_STATUS;
++
++/** info for debug purpose */
++typedef struct _uap_dbg
++{
++        /** Number of host to card command failures */
++    u32 num_cmd_host_to_card_failure;
++        /** Number of host to card Tx failures */
++    u32 num_tx_host_to_card_failure;
++} uap_dbg;
++
++/** Set thread state */
++#define OS_SET_THREAD_STATE(x)                set_current_state(x)
++
++typedef struct
++{
++    /** Task */
++    struct task_struct *task;
++    /** Queue */
++    wait_queue_head_t waitQ;
++    /** PID */
++    pid_t pid;
++    /** Private structure */
++    void *priv;
++} uap_thread;
++
++static inline void
++uap_activate_thread(uap_thread * thr)
++{
++        /** Record the thread pid */
++    thr->pid = current->pid;
++
++        /** Initialize the wait queue */
++    init_waitqueue_head(&thr->waitQ);
++}
++
++static inline void
++uap_deactivate_thread(uap_thread * thr)
++{
++    thr->pid = 0;
++    return;
++}
++
++static inline void
++uap_create_thread(int (*uapfunc) (void *), uap_thread * thr, char *name)
++{
++    thr->task = kthread_run(uapfunc, thr, "%s", name);
++}
++
++static inline int
++uap_terminate_thread(uap_thread * thr)
++{
++    /* Check if the thread is active or not */
++    if (!thr->pid)
++        return -1;
++    kthread_stop(thr->task);
++    return 0;
++}
++
++/** Data structure for the Marvell uAP device */
++typedef struct _uap_dev
++{
++        /** device name */
++    char name[DEV_NAME_LEN];
++        /** card pointer */
++    void *card;
++        /** IO port */
++    u32 ioport;
++        /** Rx unit */
++    u8 rx_unit;
++        /** Data sent:
++          TRUE - Data is sent to fw, no Tx Done received
++          FALSE - Tx done received for previous Tx */
++    BOOLEAN data_sent;
++        /** CMD sent:
++          TRUE - CMD is sent to fw, no CMD Done received
++          FALSE - CMD done received for previous CMD */
++    BOOLEAN cmd_sent;
++        /** netdev pointer */
++    struct net_device *netdev;
++} uap_dev_t, *puap_dev_t;
++
++/** Private structure for the MV device */
++struct _uap_private
++{
++        /** Device open */
++    int open;
++
++        /** Device adapter structure */
++    uap_adapter *adapter;
++        /** Device structure */
++    uap_dev_t uap_dev;
++
++        /** Net device statistics structure */
++    struct net_device_stats stats;
++
++        /** Number of Tx timeouts */
++    u32 num_tx_timeout;
++
++        /** Media connection status */
++    BOOLEAN MediaConnected;
++
++#ifdef CONFIG_PROC_FS
++    struct proc_dir_entry *proc_uap;
++    struct proc_dir_entry *proc_entry;
++#endif                          /* CONFIG_PROC_FS */
++
++        /** Firmware helper */
++    const struct firmware *fw_helper;
++        /** Firmware */
++    const struct firmware *firmware;
++        /** Hotplug device */
++    struct device *hotplug_device;
++        /** thread to service interrupts */
++    uap_thread MainThread;
++        /** Driver lock */
++    spinlock_t driver_lock;
++        /** Driver lock flags */
++    ulong driver_flags;
++
++};
++
++/** PS_CMD_ConfirmSleep */
++typedef struct _PS_CMD_ConfirmSleep
++{
++        /** SDIO Length */
++    u16 SDLen;
++    /** SDIO Type */
++    u16 SDType;
++        /** Command */
++    u16 Command;
++        /** Size */
++    u16 Size;
++        /** Sequence number */
++    u16 SeqNum;
++        /** Result */
++    u16 Result;
++} __ATTRIB_PACK__ PS_CMD_ConfirmSleep, *PPS_CMD_ConfirmSleep;
++
++/** Wlan Adapter data structure*/
++struct _uap_adapter
++{
++        /** Power save confirm sleep command */
++    PS_CMD_ConfirmSleep PSConfirmSleep;
++        /** Device status */
++    HARDWARE_STATUS HardwareStatus;
++        /** Interrupt counter */
++    u32 IntCounter;
++        /** Tx packet queue */
++    struct sk_buff_head tx_queue;
++        /** Cmd packet queue */
++    struct sk_buff_head cmd_queue;
++        /** Command sequence number */
++    u16 SeqNum;
++        /** Command buffer */
++    u8 *CmdBuf;
++        /** cmd pending flag */
++    u8 cmd_pending;
++        /** cmd wait option */
++    u8 cmd_wait_option;
++        /** Command buffer length */
++    u32 CmdSize;
++        /** Command wait queue */
++    wait_queue_head_t cmdwait_q __ATTRIB_ALIGN__;
++        /** Command wait queue state flag */
++    u8 CmdWaitQWoken;
++        /** PnP support */
++    BOOLEAN SurpriseRemoved;
++        /** Debug */
++    uap_dbg dbg;
++        /** Netlink kernel socket */
++    struct sock *nl_sk;
++        /** Semaphore for CMD */
++    SEMAPHORE CmdSem;
++         /** Power Save mode */
++    u8 psmode;
++        /** Power Save state */
++    u8 ps_state;
++        /** Number of wakeup tries */
++    u32 WakeupTries;
++};
++
++static inline int
++os_upload_rx_packet(uap_private * priv, struct sk_buff *skb)
++{
++    skb->dev = priv->uap_dev.netdev;
++    skb->protocol = eth_type_trans(skb, priv->uap_dev.netdev);
++    skb->ip_summed = CHECKSUM_UNNECESSARY;
++    if (in_interrupt())
++        netif_rx(skb);
++    else
++        netif_rx_ni(skb);
++    return 0;
++}
++
++/*
++ *  netif carrier_on/off and start(wake)/stop_queue handling
++ */
++static inline void
++os_carrier_on(uap_private * priv)
++{
++    if (!netif_carrier_ok(priv->uap_dev.netdev) &&
++        (priv->MediaConnected == TRUE)) {
++        netif_carrier_on(priv->uap_dev.netdev);
++    }
++}
++
++static inline void
++os_carrier_off(uap_private * priv)
++{
++    if (netif_carrier_ok(priv->uap_dev.netdev)) {
++        netif_carrier_off(priv->uap_dev.netdev);
++    }
++}
++
++static inline void
++os_start_queue(uap_private * priv)
++{
++    if (netif_queue_stopped(priv->uap_dev.netdev) &&
++        (priv->MediaConnected == TRUE)) {
++        netif_wake_queue(priv->uap_dev.netdev);
++    }
++}
++
++static inline void
++os_stop_queue(uap_private * priv)
++{
++    if (!netif_queue_stopped(priv->uap_dev.netdev)) {
++        netif_stop_queue(priv->uap_dev.netdev);
++    }
++}
++
++/** Interface specific header */
++#define INTF_HEADER_LEN         4
++
++/** headroom alignment for tx packet */
++#define HEADER_ALIGNMENT      8
++
++/** The number of times to try when polling for status bits */
++#define MAX_POLL_TRIES                        100
++
++/** Length of SNAP header */
++#define MRVDRV_SNAP_HEADER_LEN          8
++
++/** Extra length of Tx packet buffer */
++#define EXTRA_LEN     36
++
++/** Buffer size for ethernet Tx packets */
++#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \
++      (ETH_FRAME_LEN + sizeof(TxPD) + EXTRA_LEN)
++
++/** Buffer size for ethernet Rx packets */
++#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \
++      (ETH_FRAME_LEN + sizeof(RxPD) \
++       + MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN)
++
++/** Packet type: data, command & event */
++typedef enum _mv_type
++{
++    MV_TYPE_DAT = 0,
++    MV_TYPE_CMD = 1,
++    MV_TYPE_EVENT = 3
++} mv_type;
++
++/** Disable interrupt */
++#define OS_INT_DISABLE        spin_lock_irqsave(&priv->driver_lock, priv->driver_flags)
++/** Enable interrupt */
++#define       OS_INT_RESTORE  spin_unlock_irqrestore(&priv->driver_lock, priv->driver_flags)
++
++int uap_process_rx_packet(uap_private * priv, struct sk_buff *skb);
++void uap_interrupt(uap_private * priv);
++uap_private *uap_add_card(void *card);
++int uap_remove_card(void *card);
++int uap_process_event(uap_private * priv, u8 * payload, uint len);
++int uap_soft_reset(uap_private * priv);
++int uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len);
++
++#ifdef CONFIG_PROC_FS
++/** The proc fs interface */
++void uap_proc_entry(uap_private * priv, struct net_device *dev);
++void uap_proc_remove(uap_private * priv);
++int string_to_number(char *s);
++void uap_debug_entry(uap_private * priv, struct net_device *dev);
++void uap_debug_remove(uap_private * priv);
++#endif /* CONFIG_PROC_FS */
++
++int sbi_register(void);
++
++void sbi_unregister(void);
++int sbi_register_dev(uap_private * priv);
++int sbi_unregister_dev(uap_private * priv);
++int sbi_prog_fw_w_helper(uap_private *);
++
++int sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb);
++int sbi_enable_host_int(uap_private * priv);
++int sbi_disable_host_int(uap_private * priv);
++
++int sbi_get_int_status(uap_private * priv, u8 * ireg);
++/** Check firmware status */
++int sbi_check_fw_status(uap_private *, int);
++int sbi_prog_helper(uap_private *);
++
++int sbi_wakeup_firmware(uap_private * priv);
++
++#endif /* _UAP_DRV_H */
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_fw.h backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_fw.h
+--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_fw.h  1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_fw.h      2014-12-29 20:37:43.949097590 +0100
+@@ -0,0 +1,359 @@
++/** @file uap_fw.h
++ *
++ * @brief This file contains firmware specific defines.
++ *
++ * Copyright (C) 2008-2009, Marvell International Ltd.
++ *
++ * This software file (the "File") is distributed by Marvell International
++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
++ * (the "License").  You may use, redistribute and/or modify this File in
++ * accordance with the terms and conditions of the License, a copy of which
++ * is available along with the File in the gpl.txt file or by writing to
++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
++ *
++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
++ * this warranty disclaimer.
++ *
++ */
++/********************************************************
++Change log:
++      02/26/08: Initial creation
++********************************************************/
++
++#ifndef _UAP_FW_H
++#define _UAP_FW_H
++
++/** uap upload size */
++#define       UAP_UPLD_SIZE                   2312
++/** Packet type Micro AP */
++#define PKT_TYPE_MICROAP              1
++/** Packet type client */
++#define PKT_TYPE_CLIENT                       0
++
++/** TxPD descriptor */
++typedef struct _TxPD
++{
++        /** Bss Type */
++    u8 BssType;
++        /** Bss num */
++    u8 BssNum;
++        /** Tx packet length */
++    u16 TxPktLength;
++        /** Tx packet offset */
++    u16 TxPktOffset;
++        /** Tx packet type */
++    u16 TxPktType;
++        /** Tx Control */
++    u32 TxControl;
++        /** reserved */
++    u32 reserved[2];
++} __ATTRIB_PACK__ TxPD, *PTxPD;
++
++/** RxPD Descriptor */
++typedef struct _RxPD
++{
++        /** Bss Type */
++    u8 BssType;
++        /** Bss Num */
++    u8 BssNum;
++        /** Tx packet length */
++    u16 RxPktLength;
++        /** Tx packet offset */
++    u16 RxPktOffset;
++} __ATTRIB_PACK__ RxPD, *PRxPD;
++
++#ifdef BIG_ENDIAN
++/** Convert from 16 bit little endian format to CPU format */
++#define uap_le16_to_cpu(x) le16_to_cpu(x)
++/** Convert from 32 bit little endian format to CPU format */
++#define uap_le32_to_cpu(x) le32_to_cpu(x)
++/** Convert from 64 bit little endian format to CPU format */
++#define uap_le64_to_cpu(x) le64_to_cpu(x)
++/** Convert to 16 bit little endian format from CPU format */
++#define uap_cpu_to_le16(x) cpu_to_le16(x)
++/** Convert to 32 bit little endian format from CPU format */
++#define uap_cpu_to_le32(x) cpu_to_le32(x)
++/** Convert to 64 bit little endian format from CPU format */
++#define uap_cpu_to_le64(x) cpu_to_le64(x)
++
++/** Convert TxPD to little endian format from CPU format */
++#define endian_convert_TxPD(x);                                         \
++    {                                                                   \
++        (x)->TxPktLength = uap_cpu_to_le16((x)->TxPktLength);         \
++        (x)->TxPktOffset = uap_cpu_to_le32((x)->TxPktOffset);         \
++        (x)->TxControl = uap_cpu_to_le32((x)->TxControl);              \
++        (x)->TxPktType = uap_cpu_to_le32((x)->TxPktType);             \
++    }
++
++/** Convert RxPD from little endian format to CPU format */
++#define endian_convert_RxPD(x);                                       \
++    {                                                                 \
++        (x)->RxPktLength = uap_le16_to_cpu((x)->RxPktLength);         \
++        (x)->RxPktOffset = uap_le32_to_cpu((x)->RxPktOffset);         \
++    }
++#else /* BIG_ENDIAN */
++/** Do nothing */
++#define uap_le16_to_cpu(x) x
++/** Do nothing */
++#define uap_le32_to_cpu(x) x
++/** Do nothing */
++#define uap_le64_to_cpu(x) x
++/** Do nothing */
++#define uap_cpu_to_le16(x) x
++/** Do nothing */
++#define uap_cpu_to_le32(x) x
++/** Do nothing */
++#define uap_cpu_to_le64(x) x
++
++/** Do nothing */
++#define endian_convert_TxPD(x)
++/** Do nothing */
++#define endian_convert_RxPD(x)
++#endif /* BIG_ENDIAN */
++
++/** Host Command ID : Function initialization */
++#define HostCmd_CMD_FUNC_INIT                 0x00a9
++/** Host Command ID : Function shutdown */
++#define HostCmd_CMD_FUNC_SHUTDOWN             0x00aa
++
++/** Host Command id: SYS_INFO  */
++#define HOST_CMD_APCMD_SYS_INFO               0x00ae
++/** Host Command id: SYS_RESET  */
++#define HOST_CMD_APCMD_SYS_RESET              0x00af
++/** Host Command id: SYS_CONFIGURE  */
++#define HOST_CMD_APCMD_SYS_CONFIGURE          0x00b0
++/** Host Command id: BSS_START  */
++#define HOST_CMD_APCMD_BSS_START              0x00b1
++/** Host Command id: SYS_STOP  */
++#define HOST_CMD_APCMD_BSS_STOP               0x00b2
++/** Host Command id: STA_LIST  */
++#define HOST_CMD_APCMD_STA_LIST               0x00b3
++/** Host Command id: STA_FILTER_TABLE  */
++#define HOST_CMD_APCMD_STA_FILTER_TABLE       0x00b4
++/** Host Command id: STA_DEAUTH  */
++#define HOST_CMD_APCMD_STA_DEAUTH             0x00b5
++/** Host Command id: SOFT_RESET  */
++#define HOST_CMD_APCMD_SOFT_RESET             0x00d5
++/** Host Command id: POWER_MGMT_EXT  */
++#define HOST_CMD_POWER_MGMT_EXT               0x00ef
++/** Host Command id: SLEEP_CONFIRM*/
++#define HOST_CMD_SLEEP_CONFIRM              0x00d8
++
++/** TLV type : SSID */
++#define TLV_TYPE_SSID                         0x0000
++/** TLV type : Rates */
++#define TLV_TYPE_RATES                                0x0001
++/** TLV type : PHY DS */
++#define TLV_TYPE_PHY_DS                               0x0003
++
++/** TLV Id : Base id */
++#define PROPRIETARY_TLV_BASE_ID               0x0100
++/** TLV Id : AP_MAC_ADDRESS */
++#define MRVL_AP_MAC_ADDRESS_TLV_ID      (PROPRIETARY_TLV_BASE_ID + 43)
++/** TLV Id : Beacon period */
++#define MRVL_BEACON_PERIOD_TLV_ID       (PROPRIETARY_TLV_BASE_ID + 44)
++/** TLV Id : Dtim period */
++#define MRVL_DTIM_PERIOD_TLV_ID         (PROPRIETARY_TLV_BASE_ID + 45)
++/** TLV Id : Basic rates */
++#define MRVL_BASIC_RATES_TLV_ID         (PROPRIETARY_TLV_BASE_ID + 46)
++/** TLV Id : Tx Power */
++#define MRVL_TX_POWER_TLV_ID            (PROPRIETARY_TLV_BASE_ID + 47)
++/** TLV Id : Broadcast SSID control */
++#define MRVL_BCAST_SSID_CTL_TLV_ID      (PROPRIETARY_TLV_BASE_ID + 48)
++/** TLV Id : Preamble control */
++#define MRVL_PREAMBLE_CTL_TLV_ID        (PROPRIETARY_TLV_BASE_ID + 49)
++/** TLV Id : Antenna control */
++#define MRVL_ANTENNA_CTL_TLV_ID         (PROPRIETARY_TLV_BASE_ID + 50)
++/** TLV Id : RTS threshold */
++#define MRVL_RTS_THRESHOLD_TLV_ID       (PROPRIETARY_TLV_BASE_ID + 51)
++/** TLV Id : Radio control */
++#define MRVL_RADIO_CTL_TLV_ID           (PROPRIETARY_TLV_BASE_ID + 52)
++/** TLV Id : TX data rate */
++#define MRVL_TX_DATA_RATE_TLV_ID        (PROPRIETARY_TLV_BASE_ID + 53)
++/** TLV Id : Packet forward control */
++#define MRVL_PKT_FWD_CTL_TLV_ID         (PROPRIETARY_TLV_BASE_ID + 54)
++/** TLV Id : STA info */
++#define MRVL_STA_INFO_TLV_ID            (PROPRIETARY_TLV_BASE_ID + 55)
++/** TLV Id : STA MAC address filter */
++#define MRVL_STA_MAC_ADDR_FILTER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 56)
++/** TLV Id : STA ageout timer */
++#define MRVL_STA_AGEOUT_TIMER_TLV_ID    (PROPRIETARY_TLV_BASE_ID + 57)
++/** TLV Id : Security config */
++#define MRVL_SECURITY_CFG_TLV_ID        (PROPRIETARY_TLV_BASE_ID + 58)
++/** TLV Id : WEP KEY */
++#define MRVL_WEP_KEY_TLV_ID             (PROPRIETARY_TLV_BASE_ID + 59)
++/** TLV Id : WPA Passphrase */
++#define MRVL_WPA_PASSPHRASE_TLV_ID      (PROPRIETARY_TLV_BASE_ID + 60)
++
++/** Action get */
++#define ACTION_GET    0
++/** Action set */
++#define ACTION_SET    1
++/** Length of ethernet address */
++#ifndef       ETH_ALEN
++#define ETH_ALEN                      6
++#endif
++
++/** HostCmd_DS_GEN */
++typedef struct
++{
++    /** Command */
++    u16 Command;
++    /** Size */
++    u16 Size;
++    /** Sequence number */
++    u16 SeqNum;
++    /** Result */
++    u16 Result;
++} __ATTRIB_PACK__ HostCmd_DS_GEN;
++
++/** Size of HostCmd_DS_GEN */
++#define S_DS_GEN    sizeof(HostCmd_DS_GEN)
++
++/** _HostCmd_HEADER*/
++typedef struct
++{
++    /** Command Header : Command */
++    u16 Command;
++    /** Command Header : Size */
++    u16 Size;
++} __ATTRIB_PACK__ HostCmd_HEADER;
++
++/** HostCmd_SYS_CONFIG */
++typedef struct _HostCmd_SYS_CONFIG
++{
++        /** CMD Action GET/SET*/
++    u16 Action;
++        /** Tlv buffer */
++    u8 TlvBuffer[0];
++} __ATTRIB_PACK__ HostCmd_SYS_CONFIG;
++
++/** HostCmd_DS_POWER_MGMT_EXT */
++typedef struct _HostCmd_DS_POWER_MGMT_EXT
++{
++    /** CMD Action Get/Set*/
++    u16 action;
++    /** power mode */
++    u16 power_mode;
++} __ATTRIB_PACK__ HostCmd_DS_POWER_MGMT_EXT;
++
++/** _HostCmd_DS_COMMAND*/
++typedef struct _HostCmd_DS_COMMAND
++{
++
++        /** Command Header : Command */
++    u16 Command;
++        /** Command Header : Size */
++    u16 Size;
++        /** Command Header : Sequence number */
++    u16 SeqNum;
++        /** Command Header : Result */
++    u16 Result;
++        /** Command Body */
++    union
++    {
++        HostCmd_SYS_CONFIG sys_config;
++        HostCmd_DS_POWER_MGMT_EXT pm_cfg;
++
++    } params;
++} __ATTRIB_PACK__ HostCmd_DS_COMMAND;
++
++/** MrvlIEtypesHeader_*/
++typedef struct _MrvlIEtypesHeader
++{
++    /** Header type */
++    u16 Type;
++    /** Header length */
++    u16 Len;
++} __ATTRIB_PACK__ MrvlIEtypesHeader_t;
++
++/** MrvlIEtypes_Data_t */
++typedef struct _MrvlIEtypes_Data_t
++{
++    /** Header */
++    MrvlIEtypesHeader_t Header;
++    /** Data */
++    u8 Data[1];
++} __ATTRIB_PACK__ MrvlIEtypes_Data_t;
++
++/** MrvlIEtypes_ChanListParamSet_t */
++typedef struct _MrvlIEtypes_MacAddr_t
++{
++    /** Header */
++    MrvlIEtypesHeader_t Header;
++    /** AP MAC address */
++    u8 ApMacAddr[ETH_ALEN];
++} __ATTRIB_PACK__ MrvlIEtypes_MacAddr_t;
++
++/** Event ID: BSS started */
++#define MICRO_AP_EV_ID_BSS_START    46
++
++/** Event ID: BSS idle event */
++#define MICRO_AP_EV_BSS_IDLE       67
++
++/** Event ID: BSS active event */
++#define MICRO_AP_EV_BSS_ACTIVE             68
++
++/** Event ID: PS_AWAKE */
++#define EVENT_PS_AWAKE     0x0a
++
++/** Event ID: PS_SLEEP */
++#define EVENT_PS_SLEEP     0x0b
++
++/** PS_STATE */
++typedef enum _PS_STATE
++{
++    PS_STATE_AWAKE,
++    PS_STATE_PRE_SLEEP,
++    PS_STATE_SLEEP
++} PS_STATE;
++
++/** TLV type: AP Sleep param */
++#define TLV_TYPE_AP_SLEEP_PARAM         (PROPRIETARY_TLV_BASE_ID + 106)
++/** TLV type: AP Inactivity Sleep param */
++#define TLV_TYPE_AP_INACT_SLEEP_PARAM   (PROPRIETARY_TLV_BASE_ID + 107)
++
++/** MrvlIEtypes_sleep_param_t */
++typedef struct _MrvlIEtypes_sleep_param_t
++{
++    /** Header */
++    MrvlIEtypesHeader_t header;
++    /** control bitmap */
++    u32 ctrl_bitmap;
++    /** min_sleep */
++    u32 min_sleep;
++    /** max_sleep */
++    u32 max_sleep;
++} __ATTRIB_PACK__ MrvlIEtypes_sleep_param_t;
++
++/** MrvlIEtypes_inact_sleep_param_t */
++typedef struct _MrvlIEtypes_inact_sleep_param_t
++{
++    /** Header */
++    MrvlIEtypesHeader_t header;
++    /** inactivity timeout */
++    u32 inactivity_to;
++    /** min_awake */
++    u32 min_awake;
++    /** max_awake */
++    u32 max_awake;
++} __ATTRIB_PACK__ MrvlIEtypes_inact_sleep_param_t;
++
++/** AP_Event */
++typedef struct _AP_Event
++{
++    /** Event ID */
++    u32 EventId;
++    /*
++     * Reserved for STA_ASSOCIATED event and contains
++     * status information for the MIC_COUNTERMEASURES event.
++     */
++    /** Reserved/status */
++    u16 status;
++    /** AP MAC address */
++    u8 MacAddr[ETH_ALEN];
++} __ATTRIB_PACK__ AP_Event;
++#endif /* _UAP_FW_H */
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_headers.h backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_headers.h
+--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_headers.h     1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_headers.h 2014-12-29 20:37:43.949097590 +0100
+@@ -0,0 +1,64 @@
++/** @file uap_headers.h
++ *
++ * @brief This file contains all the necessary include file.
++ *
++  * Copyright (C) 2008-2009, Marvell International Ltd.
++ *
++ * This software file (the "File") is distributed by Marvell International
++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
++ * (the "License").  You may use, redistribute and/or modify this File in
++ * accordance with the terms and conditions of the License, a copy of which
++ * is available along with the File in the gpl.txt file or by writing to
++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
++ *
++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
++ * this warranty disclaimer.
++ *
++ */
++#ifndef _UAP_HEADERS_H
++#define _UAP_HEADERS_H
++
++/* Linux header files */
++#include    <linux/kernel.h>
++#include    <linux/module.h>
++#include    <linux/init.h>
++#include    <linux/version.h>
++#include    <linux/param.h>
++#include    <linux/types.h>
++#include    <linux/interrupt.h>
++#include    <linux/proc_fs.h>
++#include    <linux/kthread.h>
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
++#include    <linux/semaphore.h>
++#else
++#include    <asm/semaphore.h>
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
++#include    <linux/config.h>
++#endif
++
++/* Net header files */
++#include    <linux/netdevice.h>
++#include    <linux/net.h>
++#include    <linux/skbuff.h>
++#include    <linux/if_ether.h>
++#include    <linux/etherdevice.h>
++#include    <net/sock.h>
++#include    <linux/netlink.h>
++#include    <linux/firmware.h>
++#include    <linux/delay.h>
++
++#include    "uap_drv.h"
++#include    "uap_fw.h"
++
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/sdio_ids.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/card.h>
++#include "uap_sdio_mmc.h"
++
++#endif /* _UAP_HEADERS_H */
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_main.c backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_main.c
+--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_main.c        1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_main.c    2014-12-29 20:37:43.952431125 +0100
+@@ -0,0 +1,1817 @@
++/** @file uap_main.c
++  * @brief This file contains the major functions in uAP
++  * driver. It includes init, exit etc..
++  * This file also contains the initialization for SW,
++  * FW and HW
++  *
++  * Copyright (C) 2008-2009, Marvell International Ltd.
++  *
++  * This software file (the "File") is distributed by Marvell International
++  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
++  * (the "License").  You may use, redistribute and/or modify this File in
++  * accordance with the terms and conditions of the License, a copy of which
++  * is available along with the File in the gpl.txt file or by writing to
++  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
++  *
++  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
++  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
++  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
++  * this warranty disclaimer.
++  *
++  */
++/**
++  * @mainpage uAP Linux Driver
++  *
++  * @section overview_sec Overview
++  *
++  * This is Linux reference driver for Marvell uAP.
++  *
++  * @section copyright_sec Copyright
++  *
++  * Copyright (C) 2008, Marvell International Ltd.
++  *
++  */
++
++#include      "uap_headers.h"
++
++/**
++ * the global variable of a pointer to uap_private
++ * structure variable
++ */
++uap_private *uappriv = NULL;
++#ifdef DEBUG_LEVEL1
++#define DEFAULT_DEBUG_MASK    (DBG_MSG | DBG_FATAL | DBG_ERROR)
++u32 drvdbg = DEFAULT_DEBUG_MASK;
++#endif
++/** Helper name */
++char *helper_name = NULL;
++/** Firmware name */
++char *fw_name = NULL;
++
++/** Semaphore for add/remove card */
++SEMAPHORE AddRemoveCardSem;
++
++/********************************************************
++              Local Functions
++********************************************************/
++/**
++ *  @brief This function send sleep confirm command to firmware
++ *
++ *  @param priv       A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE
++ */
++static int
++uap_dnld_sleep_confirm_cmd(uap_private * priv)
++{
++    uap_adapter *Adapter = priv->adapter;
++    int ret = UAP_STATUS_SUCCESS;
++    ENTER();
++    PRINTM(CMND, "Sleep confirm\n");
++    Adapter->cmd_pending = TRUE;
++    Adapter->cmd_wait_option = HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM;
++    ret =
++        sbi_host_to_card(priv, (u8 *) & Adapter->PSConfirmSleep,
++                         sizeof(PS_CMD_ConfirmSleep));
++    if (ret != UAP_STATUS_SUCCESS) {
++        Adapter->ps_state = PS_STATE_AWAKE;
++        Adapter->cmd_pending = FALSE;
++        Adapter->cmd_wait_option = FALSE;
++    }
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function process sleep confirm resp from firmware
++ *
++ *  @param priv       A pointer to uap_private structure
++ *  @param resp       A pointer to resp buf
++ *  @param resp_len   resp buf len
++ *  @return      UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE
++ */
++int
++uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    HostCmd_DS_COMMAND *cmd;
++    uap_adapter *Adapter = priv->adapter;
++    ENTER();
++    PRINTM(CMND, "Sleep confirm resp\n");
++    if (!resp_len) {
++        PRINTM(ERROR, "Cmd Size is 0\n");
++        ret = -EFAULT;
++        goto done;
++    }
++    cmd = (HostCmd_DS_COMMAND *) resp;
++    cmd->Result = uap_le16_to_cpu(cmd->Result);
++    if (cmd->Result != UAP_STATUS_SUCCESS) {
++        PRINTM(ERROR, "HOST_CMD_APCMD_PS_SLEEP_CONFIRM fail=%x\n", cmd->Result);
++        ret = -EFAULT;
++    }
++  done:
++    if (ret == UAP_STATUS_SUCCESS)
++        Adapter->ps_state = PS_STATE_SLEEP;
++    else
++        Adapter->ps_state = PS_STATE_AWAKE;
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function checks condition and prepares to
++ *  send sleep confirm command to firmware if OK.
++ *
++ *  @param priv       A pointer to uap_private structure
++ *  @return           n/a
++ */
++static void
++uap_ps_cond_check(uap_private * priv)
++{
++    uap_adapter *Adapter = priv->adapter;
++
++    ENTER();
++    if (!priv->uap_dev.cmd_sent &&
++        !Adapter->cmd_pending && !Adapter->IntCounter) {
++        uap_dnld_sleep_confirm_cmd(priv);
++    } else {
++        PRINTM(INFO, "Delay Sleep Confirm (%s%s%s)\n",
++               (priv->uap_dev.cmd_sent) ? "D" : "",
++               (Adapter->cmd_pending) ? "C" : "",
++               (Adapter->IntCounter) ? "I" : "");
++    }
++    LEAVE();
++}
++
++/**
++ *  @brief This function add cmd to cmdQ and waiting for response
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param skb           A pointer to the skb for process
++ *  @param wait_option Wait option
++ *  @return      UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE
++ */
++static int
++uap_process_cmd(uap_private * priv, struct sk_buff *skb, u8 wait_option)
++{
++    uap_adapter *Adapter = priv->adapter;
++    int ret = UAP_STATUS_SUCCESS;
++    HostCmd_DS_COMMAND *cmd;
++    u8 *headptr;
++    ENTER();
++    if (Adapter->HardwareStatus != HWReady) {
++        PRINTM(ERROR, "Hw not ready, uap_process_cmd\n");
++        kfree(skb);
++        LEAVE();
++        return -EFAULT;
++    }
++    skb->cb[0] = wait_option;
++    headptr = skb->data;
++    *(u16 *) & headptr[0] = uap_cpu_to_le16(skb->len);
++    *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_CMD);
++    cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
++    Adapter->SeqNum++;
++    cmd->SeqNum = uap_cpu_to_le16(Adapter->SeqNum);
++    PRINTM(CMND, "process_cmd: %x\n", cmd->Command);
++    DBG_HEXDUMP(CMD_D, "process_cmd", (u8 *) cmd, cmd->Size);
++    if (!wait_option) {
++        skb_queue_tail(&priv->adapter->cmd_queue, skb);
++        wake_up_interruptible(&priv->MainThread.waitQ);
++        LEAVE();
++        return ret;
++    }
++    if (OS_ACQ_SEMAPHORE_BLOCK(&Adapter->CmdSem)) {
++        PRINTM(ERROR, "Acquire semaphore error, uap_prepare_cmd\n");
++        kfree(skb);
++        LEAVE();
++        return -EBUSY;
++    }
++    skb_queue_tail(&priv->adapter->cmd_queue, skb);
++    Adapter->CmdWaitQWoken = FALSE;
++    wake_up_interruptible(&priv->MainThread.waitQ);
++    /* Sleep until response is generated by FW */
++    if (wait_option == HostCmd_OPTION_WAITFORRSP_TIMEOUT) {
++        if (!os_wait_interruptible_timeout
++            (Adapter->cmdwait_q, Adapter->CmdWaitQWoken, MRVDRV_TIMER_20S)) {
++            PRINTM(ERROR, "Cmd timeout\n");
++            Adapter->cmd_pending = FALSE;
++            ret = -EFAULT;
++        }
++    } else
++        wait_event_interruptible(Adapter->cmdwait_q, Adapter->CmdWaitQWoken);
++    OS_REL_SEMAPHORE(&Adapter->CmdSem);
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief Inspect the response buffer for pointers to expected TLVs
++ *
++ *
++ *  @param pTlv        Pointer to the start of the TLV buffer to parse
++ *  @param tlvBufSize  Size of the TLV buffer
++ *  @param reqTlvType  request tlv's tlvtype
++ *  @param ppTlv       Output parameter: Pointer to the request TLV if found
++ *
++ *  @return            void
++ */
++static void
++uap_get_tlv_ptrs(MrvlIEtypes_Data_t * pTlv, int tlvBufSize,
++                 u16 reqTlvType, MrvlIEtypes_Data_t ** ppTlv)
++{
++    MrvlIEtypes_Data_t *pCurrentTlv;
++    int tlvBufLeft;
++    u16 tlvType;
++    u16 tlvLen;
++
++    ENTER();
++    pCurrentTlv = pTlv;
++    tlvBufLeft = tlvBufSize;
++    *ppTlv = NULL;
++    PRINTM(INFO, "uap_get_tlv: tlvBufSize = %d, reqTlvType=%x\n", tlvBufSize,
++           reqTlvType);
++    while (tlvBufLeft >= sizeof(MrvlIEtypesHeader_t)) {
++        tlvType = uap_le16_to_cpu(pCurrentTlv->Header.Type);
++        tlvLen = uap_le16_to_cpu(pCurrentTlv->Header.Len);
++        if (reqTlvType == tlvType)
++            *ppTlv = (MrvlIEtypes_Data_t *) pCurrentTlv;
++        if (*ppTlv) {
++            HEXDUMP("TLV Buf", (u8 *) * ppTlv, tlvLen);
++            break;
++        }
++        tlvBufLeft -= (sizeof(pTlv->Header) + tlvLen);
++        pCurrentTlv = (MrvlIEtypes_Data_t *) (pCurrentTlv->Data + tlvLen);
++    }                           /* while */
++    LEAVE();
++}
++
++/**
++ *  @brief This function get mac
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
++ */
++static int
++uap_get_mac_address(uap_private * priv)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u32 CmdSize;
++    HostCmd_DS_COMMAND *cmd;
++    uap_adapter *Adapter = priv->adapter;
++    struct sk_buff *skb;
++    MrvlIEtypes_MacAddr_t *pMacAddrTlv;
++    MrvlIEtypes_Data_t *pTlv;
++    u16 tlvBufSize;
++    ENTER();
++    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
++    if (!skb) {
++        PRINTM(ERROR, "No free skb\n");
++        ret = -ENOMEM;
++        goto done;
++    }
++    CmdSize =
++        S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t);
++    cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
++    cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
++    cmd->Size = uap_cpu_to_le16(CmdSize);
++    cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_GET);
++    pMacAddrTlv =
++        (MrvlIEtypes_MacAddr_t *) (skb->data + INTF_HEADER_LEN + S_DS_GEN +
++                                   sizeof(HostCmd_SYS_CONFIG));
++    pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID);
++    pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN);
++    skb_put(skb, CmdSize + INTF_HEADER_LEN);
++    if (UAP_STATUS_SUCCESS !=
++        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
++        PRINTM(ERROR, "Fail to process cmd SYS_CONFIGURE Query\n");
++        ret = -EFAULT;
++        goto done;
++    }
++    if (!Adapter->CmdSize) {
++        PRINTM(ERROR, "Cmd Size is 0\n");
++        ret = -EFAULT;
++        goto done;
++    }
++    cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf;
++    cmd->Result = uap_le16_to_cpu(cmd->Result);
++    if (cmd->Result != UAP_STATUS_SUCCESS) {
++        PRINTM(ERROR, "uap_get_mac_address fail=%x\n", cmd->Result);
++        ret = -EFAULT;
++        goto done;
++    }
++    pTlv =
++        (MrvlIEtypes_Data_t *) (Adapter->CmdBuf + S_DS_GEN +
++                                sizeof(HostCmd_SYS_CONFIG));
++    tlvBufSize = Adapter->CmdSize - S_DS_GEN - sizeof(HostCmd_SYS_CONFIG);
++    uap_get_tlv_ptrs(pTlv, tlvBufSize, MRVL_AP_MAC_ADDRESS_TLV_ID,
++                     (MrvlIEtypes_Data_t **) & pMacAddrTlv);
++    if (pMacAddrTlv) {
++        memcpy(priv->uap_dev.netdev->dev_addr, pMacAddrTlv->ApMacAddr,
++               ETH_ALEN);
++        HEXDUMP("Original MAC addr", priv->uap_dev.netdev->dev_addr, ETH_ALEN);
++    }
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function checks the conditions and sends packet to device
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param skb           A pointer to the skb for process
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++uap_process_tx(uap_private * priv, struct sk_buff *skb)
++{
++    uap_adapter *Adapter = priv->adapter;
++    int ret = UAP_STATUS_SUCCESS;
++    TxPD *pLocalTxPD;
++    u8 *headptr;
++    struct sk_buff *newskb;
++    int newheadlen;
++    ENTER();
++    ASSERT(skb);
++    if (!skb) {
++        LEAVE();
++        return UAP_STATUS_FAILURE;
++    }
++    if (skb_headroom(skb) < (sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT)) {
++        newheadlen = sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT;
++        PRINTM(WARN, "Tx: Insufficient skb headroom %d\n", skb_headroom(skb));
++        /* Insufficient skb headroom - allocate a new skb */
++        newskb = skb_realloc_headroom(skb, newheadlen);
++        if (unlikely(newskb == NULL)) {
++            PRINTM(ERROR, "Tx: Cannot allocate skb\n");
++            ret = UAP_STATUS_FAILURE;
++            goto done;
++        }
++        kfree_skb(skb);
++        skb = newskb;
++        PRINTM(INFO, "new skb headroom %d\n", skb_headroom(skb));
++    }
++    /* headptr should be aligned */
++    headptr = skb->data - sizeof(TxPD) - INTF_HEADER_LEN;
++    headptr = (u8 *) ((u32) headptr & ~((u32) (HEADER_ALIGNMENT - 1)));
++
++    pLocalTxPD = (TxPD *) (headptr + INTF_HEADER_LEN);
++    memset(pLocalTxPD, 0, sizeof(TxPD));
++    pLocalTxPD->BssType = PKT_TYPE_MICROAP;
++    pLocalTxPD->TxPktLength = skb->len;
++    /* offset of actual data */
++    pLocalTxPD->TxPktOffset = (long) skb->data - (long) pLocalTxPD;
++    endian_convert_TxPD(pLocalTxPD);
++    *(u16 *) & headptr[0] =
++        uap_cpu_to_le16(skb->len + ((long) skb->data - (long) headptr));
++    *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_DAT);
++    ret =
++        sbi_host_to_card(priv, headptr,
++                         skb->len + ((long) skb->data - (long) headptr));
++    if (ret) {
++        PRINTM(ERROR, "uap_process_tx Error: sbi_host_to_card failed: 0x%X\n",
++               ret);
++        Adapter->dbg.num_tx_host_to_card_failure++;
++        goto done;
++    }
++    PRINTM(DATA, "Data => FW\n");
++    DBG_HEXDUMP(DAT_D, "Tx", headptr,
++                MIN(skb->len + sizeof(TxPD), DATA_DUMP_LEN));
++  done:
++    /* Freed skb */
++    kfree_skb(skb);
++    LEAVE();
++    return ret;
++}
++
++static struct netlink_kernel_cfg cfg = {
++      .groups = NL_MULTICAST_GROUP,
++};
++
++/**
++ *  @brief This function initializes the adapter structure
++ *  and set default value to the member of adapter.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++uap_init_sw(uap_private * priv)
++{
++    uap_adapter *Adapter = priv->adapter;
++
++    ENTER();
++
++    if (!(Adapter->CmdBuf = kmalloc(MRVDRV_SIZE_OF_CMD_BUFFER, GFP_KERNEL))) {
++        PRINTM(INFO, "Failed to allocate command buffer!\n");
++        LEAVE();
++        return UAP_STATUS_FAILURE;
++    }
++
++    Adapter->cmd_pending = FALSE;
++    Adapter->CmdWaitQWoken = FALSE;
++    Adapter->ps_state = PS_STATE_AWAKE;
++    Adapter->WakeupTries = 0;
++
++    memset(&Adapter->PSConfirmSleep, 0, sizeof(PS_CMD_ConfirmSleep));
++        /** SDIO header */
++    Adapter->PSConfirmSleep.SDLen =
++        uap_cpu_to_le16(sizeof(PS_CMD_ConfirmSleep));
++    Adapter->PSConfirmSleep.SDType = uap_cpu_to_le16(MV_TYPE_CMD);
++    Adapter->PSConfirmSleep.SeqNum = 0;
++    Adapter->PSConfirmSleep.Command = uap_cpu_to_le16(HOST_CMD_SLEEP_CONFIRM);
++    Adapter->PSConfirmSleep.Size = uap_cpu_to_le16(sizeof(HostCmd_DS_GEN));
++    Adapter->PSConfirmSleep.Result = 0;
++
++    init_waitqueue_head(&Adapter->cmdwait_q);
++    OS_INIT_SEMAPHORE(&Adapter->CmdSem);
++
++    skb_queue_head_init(&Adapter->tx_queue);
++    skb_queue_head_init(&Adapter->cmd_queue);
++
++    /* Status variable */
++    Adapter->HardwareStatus = HWInitializing;
++
++    /* PnP support */
++    Adapter->SurpriseRemoved = FALSE;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
++    Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL,
++                                           NL_MULTICAST_GROUP, NULL,
++                                           THIS_MODULE);
++#else
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
++    Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL,
++                                           NL_MULTICAST_GROUP, NULL, NULL,
++                                           THIS_MODULE);
++#else
++    Adapter->nl_sk = netlink_kernel_create(&init_net, NETLINK_MARVELL, &cfg);
++#endif
++#endif
++    if (!Adapter->nl_sk) {
++        PRINTM(ERROR,
++               "Could not initialize netlink event passing mechanism!\n");
++    }
++    LEAVE();
++    return UAP_STATUS_SUCCESS;
++}
++
++/**
++ *  @brief This function sends FUNC_INIT command to firmware
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
++ */
++static int
++uap_func_init(uap_private * priv)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u32 CmdSize;
++    HostCmd_DS_GEN *cmd;
++    uap_adapter *Adapter = priv->adapter;
++    struct sk_buff *skb;
++    ENTER();
++    if (Adapter->HardwareStatus != HWReady) {
++        PRINTM(ERROR, "uap_func_init:Hardware is not ready!\n");
++        ret = -EFAULT;
++        goto done;
++    }
++    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
++    if (!skb) {
++        PRINTM(ERROR, "No free skb\n");
++        ret = -ENOMEM;
++        goto done;
++    }
++    CmdSize = sizeof(HostCmd_DS_GEN);
++    cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
++    cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_INIT);
++    cmd->Size = uap_cpu_to_le16(CmdSize);
++    skb_put(skb, CmdSize + INTF_HEADER_LEN);
++    PRINTM(CMND, "HostCmd_CMD_FUNC_INIT\n");
++    if (UAP_STATUS_SUCCESS !=
++        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
++        PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_INIT\n");
++        ret = -EFAULT;
++        goto done;
++    }
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function sends FUNC_SHUTDOWN command to firmware
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
++ */
++static int __exit
++uap_func_shutdown(uap_private * priv)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u32 CmdSize;
++    HostCmd_DS_GEN *cmd;
++    uap_adapter *Adapter = priv->adapter;
++    struct sk_buff *skb;
++    ENTER();
++    if (Adapter->HardwareStatus != HWReady) {
++        PRINTM(ERROR, "uap_func_shutdown:Hardware is not ready!\n");
++        ret = -EFAULT;
++        goto done;
++    }
++    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
++    if (!skb) {
++        PRINTM(ERROR, "No free skb\n");
++        ret = -ENOMEM;
++        goto done;
++    }
++    CmdSize = sizeof(HostCmd_DS_GEN);
++    cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
++    cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_SHUTDOWN);
++    cmd->Size = uap_cpu_to_le16(CmdSize);
++    skb_put(skb, CmdSize + INTF_HEADER_LEN);
++    PRINTM(CMND, "HostCmd_CMD_FUNC_SHUTDOWN\n");
++    if (UAP_STATUS_SUCCESS !=
++        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
++        PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_SHUTDOWN\n");
++        ret = -EFAULT;
++        goto done;
++    }
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function initializes firmware
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++uap_init_fw(uap_private * priv)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    ENTER();
++    sbi_disable_host_int(priv);
++    /* Check if firmware is already running */
++    if (sbi_check_fw_status(priv, 1) == UAP_STATUS_SUCCESS) {
++        PRINTM(MSG, "UAP FW already running! Skip FW download\n");
++    } else {
++        if ((ret = request_firmware(&priv->fw_helper, helper_name,
++                                    priv->hotplug_device)) < 0) {
++            PRINTM(FATAL,
++                   "request_firmware() failed (helper), error code = %#x\n",
++                   ret);
++            goto done;
++        }
++
++        /* Download the helper */
++        ret = sbi_prog_helper(priv);
++
++        if (ret) {
++            PRINTM(FATAL,
++                   "Bootloader in invalid state! Helper download failed!\n");
++            ret = UAP_STATUS_FAILURE;
++            goto done;
++        }
++        if ((ret = request_firmware(&priv->firmware, fw_name,
++                                    priv->hotplug_device)) < 0) {
++            PRINTM(FATAL, "request_firmware() failed, error code = %#x\n", ret);
++            goto done;
++        }
++
++        /* Download the main firmware via the helper firmware */
++        if (sbi_prog_fw_w_helper(priv)) {
++            PRINTM(FATAL, "UAP FW download failed!\n");
++            ret = UAP_STATUS_FAILURE;
++            goto done;
++        }
++        /* Check if the firmware is downloaded successfully or not */
++        if (sbi_check_fw_status(priv, MAX_FIRMWARE_POLL_TRIES) ==
++            UAP_STATUS_FAILURE) {
++            PRINTM(FATAL, "FW failed to be active in time!\n");
++            ret = UAP_STATUS_FAILURE;
++            goto done;
++        }
++        PRINTM(MSG, "UAP FW is active\n");
++    }
++    sbi_enable_host_int(priv);
++    priv->adapter->HardwareStatus = HWReady;
++    if (uap_func_init(priv) != UAP_STATUS_SUCCESS) {
++        ret = UAP_STATUS_FAILURE;
++        goto done;
++    }
++  done:
++    if (priv->fw_helper)
++        release_firmware(priv->fw_helper);
++    if (priv->firmware)
++        release_firmware(priv->firmware);
++    LEAVE();
++    return ret;
++
++}
++
++/**
++ *  @brief This function frees the structure of adapter
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      n/a
++ */
++static void
++uap_free_adapter(uap_private * priv)
++{
++    uap_adapter *Adapter = priv->adapter;
++
++    ENTER();
++
++    if (Adapter) {
++        if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) {
++            sock_release((Adapter->nl_sk)->sk_socket);
++            Adapter->nl_sk = NULL;
++        }
++        if (Adapter->CmdBuf)
++            kfree(Adapter->CmdBuf);
++        skb_queue_purge(&priv->adapter->tx_queue);
++        skb_queue_purge(&priv->adapter->cmd_queue);
++        /* Free the adapter object itself */
++        kfree(Adapter);
++        priv->adapter = NULL;
++    }
++
++    LEAVE();
++}
++
++/**
++ *  @brief This function handles the major job in uap driver.
++ *  it handles the event generated by firmware, rx data received
++ *  from firmware and tx data sent from kernel.
++ *
++ *  @param data    A pointer to uap_thread structure
++ *  @return        BT_STATUS_SUCCESS
++ */
++static int
++uap_service_main_thread(void *data)
++{
++    uap_thread *thread = data;
++    uap_private *priv = thread->priv;
++    uap_adapter *Adapter = priv->adapter;
++    wait_queue_t wait;
++    u8 ireg = 0;
++    struct sk_buff *skb;
++    ENTER();
++    uap_activate_thread(thread);
++    init_waitqueue_entry(&wait, current);
++    current->flags |= PF_NOFREEZE;
++
++    for (;;) {
++        add_wait_queue(&thread->waitQ, &wait);
++        OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE);
++        if ((Adapter->WakeupTries) ||
++            (!Adapter->IntCounter && Adapter->ps_state == PS_STATE_PRE_SLEEP) ||
++            (!priv->adapter->IntCounter
++             && (priv->uap_dev.data_sent ||
++                 skb_queue_empty(&priv->adapter->tx_queue))
++             && (priv->uap_dev.cmd_sent || Adapter->cmd_pending ||
++                 skb_queue_empty(&priv->adapter->cmd_queue))
++            )) {
++            PRINTM(INFO, "Main: Thread sleeping...\n");
++            schedule();
++        }
++        OS_SET_THREAD_STATE(TASK_RUNNING);
++        remove_wait_queue(&thread->waitQ, &wait);
++        if (kthread_should_stop() || Adapter->SurpriseRemoved) {
++            PRINTM(INFO, "main-thread: break from main thread: "
++                   "SurpriseRemoved=0x%x\n", Adapter->SurpriseRemoved);
++            /* Cancel pending command */
++            if (Adapter->cmd_pending == TRUE) {
++                /* Wake up cmd Q */
++                Adapter->CmdWaitQWoken = TRUE;
++                wake_up_interruptible(&Adapter->cmdwait_q);
++            }
++            break;
++        }
++
++        PRINTM(INFO, "Main: Thread waking up...\n");
++        if (priv->adapter->IntCounter) {
++            OS_INT_DISABLE;
++            Adapter->IntCounter = 0;
++            OS_INT_RESTORE;
++            sbi_get_int_status(priv, &ireg);
++        } else if ((priv->adapter->ps_state == PS_STATE_SLEEP) &&
++                   (!skb_queue_empty(&priv->adapter->cmd_queue) ||
++                    !skb_queue_empty(&priv->adapter->tx_queue))) {
++            priv->adapter->WakeupTries++;
++            PRINTM(CMND, "%lu : Wakeup device...\n", os_time_get());
++            sbi_wakeup_firmware(priv);
++            continue;
++        }
++        if (Adapter->ps_state == PS_STATE_PRE_SLEEP)
++            uap_ps_cond_check(priv);
++
++        /* The PS state is changed during processing of Sleep Request event
++           above */
++        if ((Adapter->ps_state == PS_STATE_SLEEP) ||
++            (Adapter->ps_state == PS_STATE_PRE_SLEEP))
++            continue;
++        /* Execute the next command */
++        if (!priv->uap_dev.cmd_sent && !Adapter->cmd_pending &&
++            (Adapter->HardwareStatus == HWReady)) {
++            if (!skb_queue_empty(&priv->adapter->cmd_queue)) {
++                skb = skb_dequeue(&priv->adapter->cmd_queue);
++                if (skb) {
++                    Adapter->CmdSize = 0;
++                    Adapter->cmd_pending = TRUE;
++                    Adapter->cmd_wait_option = skb->cb[0];
++                    if (sbi_host_to_card(priv, skb->data, skb->len)) {
++                        PRINTM(ERROR, "Cmd:sbi_host_to_card failed!\n");
++                        Adapter->cmd_pending = FALSE;
++                        Adapter->dbg.num_cmd_host_to_card_failure++;
++                        /* Wake up cmd Q */
++                        Adapter->CmdWaitQWoken = TRUE;
++                        wake_up_interruptible(&Adapter->cmdwait_q);
++                    } else {
++                        if (Adapter->cmd_wait_option ==
++                            HostCmd_OPTION_WAITFORSEND) {
++                            /* Wake up cmd Q */
++                            Adapter->CmdWaitQWoken = TRUE;
++                            wake_up_interruptible(&Adapter->cmdwait_q);
++                            Adapter->cmd_wait_option = FALSE;
++                        }
++                    }
++                    kfree_skb(skb);
++                }
++            }
++        }
++        if (!priv->uap_dev.data_sent && (Adapter->HardwareStatus == HWReady)) {
++            if (!skb_queue_empty(&priv->adapter->tx_queue)) {
++                skb = skb_dequeue(&priv->adapter->tx_queue);
++                if (skb) {
++                    if (uap_process_tx(priv, skb)) {
++                        priv->stats.tx_dropped++;
++                        priv->stats.tx_errors++;
++                        os_start_queue(priv);
++                    } else {
++                        priv->stats.tx_packets++;
++                        priv->stats.tx_bytes += skb->len;
++                    }
++
++                }
++            }
++        }
++    }
++    uap_deactivate_thread(thread);
++    LEAVE();
++    return UAP_STATUS_SUCCESS;
++}
++
++/**
++ *  @brief uap hostcmd ioctl handler
++ *
++ *  @param dev      A pointer to net_device structure
++ *  @param req      A pointer to ifreq structure
++ *  @return         UAP_STATUS_SUCCESS --success, otherwise fail
++ */
++/*********  format of ifr_data *************/
++/*    buf_len + Hostcmd_body             */
++/*    buf_len: 4 bytes                     */
++/*             the length of the buf which */
++/*             can be used to return data  */
++/*             to application            */
++/*    Hostcmd_body                       */
++/*******************************************/
++static int
++uap_hostcmd_ioctl(struct net_device *dev, struct ifreq *req)
++{
++    u32 buf_len;
++    HostCmd_HEADER head;
++    uap_private *priv = (uap_private *) netdev_priv(dev);
++    uap_adapter *Adapter = priv->adapter;
++    int ret = UAP_STATUS_SUCCESS;
++    struct sk_buff *skb;
++
++    ENTER();
++
++    /* Sanity check */
++    if (req->ifr_data == NULL) {
++        PRINTM(ERROR, "uap_hostcmd_ioctl() corrupt data\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    if (copy_from_user(&buf_len, req->ifr_data, sizeof(buf_len))) {
++        PRINTM(ERROR, "Copy from user failed\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    memset(&head, 0, sizeof(HostCmd_HEADER));
++    /* Get the command size from user space */
++    if (copy_from_user
++        (&head, req->ifr_data + sizeof(buf_len), sizeof(HostCmd_HEADER))) {
++        PRINTM(ERROR, "Copy from user failed\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    head.Size = uap_le16_to_cpu(head.Size);
++    if (head.Size > MRVDRV_SIZE_OF_CMD_BUFFER) {
++        PRINTM(ERROR, "CmdSize too big=%d\n", head.Size);
++        LEAVE();
++        return -EFAULT;
++    }
++    PRINTM(CMND, "ioctl: hostcmd=%x, size=%d,buf_len=%d\n", head.Command,
++           head.Size, buf_len);
++    skb = dev_alloc_skb(head.Size + INTF_HEADER_LEN);
++    if (!skb) {
++        PRINTM(ERROR, "No free skb\n");
++        LEAVE();
++        return -ENOMEM;
++    }
++
++    /* Get the command from user space */
++    if (copy_from_user
++        (skb->data + INTF_HEADER_LEN, req->ifr_data + sizeof(buf_len),
++         head.Size)) {
++        PRINTM(ERROR, "Copy from user failed\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    skb_put(skb, head.Size + INTF_HEADER_LEN);
++    if (UAP_STATUS_SUCCESS !=
++        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) {
++        PRINTM(ERROR, "Fail to process cmd\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    if (!Adapter->CmdSize) {
++        PRINTM(ERROR, "Cmd Size is 0\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    if (Adapter->CmdSize > buf_len) {
++        PRINTM(ERROR, "buf_len is too small\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    /* Copy to user */
++    if (copy_to_user
++        (req->ifr_data + sizeof(buf_len), Adapter->CmdBuf, Adapter->CmdSize)) {
++        PRINTM(ERROR, "Copy to user failed!\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief uap power mode ioctl handler
++ *
++ *  @param dev      A pointer to net_device structure
++ *  @param req      A pointer to ifreq structure
++ *  @return         UAP_STATUS_SUCCESS --success, otherwise fail
++ */
++static int
++uap_power_mode_ioctl(struct net_device *dev, struct ifreq *req)
++{
++    ps_mgmt pm_cfg;
++    int ret = UAP_STATUS_SUCCESS;
++    uap_private *priv = (uap_private *) netdev_priv(dev);
++    uap_adapter *Adapter = priv->adapter;
++    struct sk_buff *skb = NULL;
++    HostCmd_DS_COMMAND *cmd;
++    u32 CmdSize;
++    u8 *tlv = NULL;
++    MrvlIEtypes_sleep_param_t *sleep_tlv = NULL;
++    MrvlIEtypes_inact_sleep_param_t *inact_tlv = NULL;
++    u16 tlv_buf_left = 0;
++    MrvlIEtypesHeader_t *tlvbuf = NULL;
++    u16 tlv_type = 0;
++    u16 tlv_len = 0;
++
++    ENTER();
++
++    /* Sanity check */
++    if (req->ifr_data == NULL) {
++        PRINTM(ERROR, "uap_power_mode_ioctl() corrupt data\n");
++        LEAVE();
++        return -EFAULT;
++    }
++
++    memset(&pm_cfg, 0, sizeof(ps_mgmt));
++    if (copy_from_user(&pm_cfg, req->ifr_data, sizeof(ps_mgmt))) {
++        PRINTM(ERROR, "Copy from user failed\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    PRINTM(CMND,
++           "ioctl power: flag=0x%x ps_mode=%d ctrl_bitmap=%d min_sleep=%d max_sleep=%d "
++           "inact_to=%d min_awake=%d max_awake=%d\n", pm_cfg.flags,
++           (int) pm_cfg.ps_mode, (int) pm_cfg.sleep_param.ctrl_bitmap,
++           (int) pm_cfg.sleep_param.min_sleep,
++           (int) pm_cfg.sleep_param.max_sleep,
++           (int) pm_cfg.inact_param.inactivity_to,
++           (int) pm_cfg.inact_param.min_awake,
++           (int) pm_cfg.inact_param.max_awake);
++
++    if (pm_cfg.
++        flags & ~(PS_FLAG_PS_MODE | PS_FLAG_SLEEP_PARAM |
++                  PS_FLAG_INACT_SLEEP_PARAM)) {
++        PRINTM(ERROR, "Invalid parameter: flags = 0x%x\n", pm_cfg.flags);
++        ret = -EINVAL;
++        goto done;
++    }
++    if (pm_cfg.ps_mode > PS_MODE_INACTIVITY) {
++        PRINTM(ERROR, "Invalid parameter: ps_mode = %d\n", (int) pm_cfg.flags);
++        ret = -EINVAL;
++        goto done;
++    }
++
++    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
++    if (!skb) {
++        PRINTM(INFO, "No free skb\n");
++        ret = -ENOMEM;
++        goto done;
++    }
++
++    CmdSize = S_DS_GEN + sizeof(HostCmd_DS_POWER_MGMT_EXT);
++
++    cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
++    cmd->Command = uap_cpu_to_le16(HOST_CMD_POWER_MGMT_EXT);
++    if (!pm_cfg.flags) {
++        cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_GET);
++    } else {
++        cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_SET);
++        cmd->params.pm_cfg.power_mode = uap_cpu_to_le16(pm_cfg.ps_mode);
++        tlv = (u8 *) & cmd->params.pm_cfg + sizeof(HostCmd_DS_POWER_MGMT_EXT);
++
++        if ((pm_cfg.ps_mode) && (pm_cfg.flags & PS_FLAG_SLEEP_PARAM)) {
++            sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlv;
++            sleep_tlv->header.Type = uap_cpu_to_le16(TLV_TYPE_AP_SLEEP_PARAM);
++            sleep_tlv->header.Len =
++                uap_cpu_to_le16(sizeof(MrvlIEtypes_sleep_param_t) -
++                                sizeof(MrvlIEtypesHeader_t));
++            sleep_tlv->ctrl_bitmap =
++                uap_cpu_to_le32(pm_cfg.sleep_param.ctrl_bitmap);
++            sleep_tlv->min_sleep =
++                uap_cpu_to_le32(pm_cfg.sleep_param.min_sleep);
++            sleep_tlv->max_sleep =
++                uap_cpu_to_le32(pm_cfg.sleep_param.max_sleep);
++            CmdSize += sizeof(MrvlIEtypes_sleep_param_t);
++            tlv += sizeof(MrvlIEtypes_sleep_param_t);
++        }
++        if ((pm_cfg.ps_mode == PS_MODE_INACTIVITY) &&
++            (pm_cfg.flags & PS_FLAG_INACT_SLEEP_PARAM)) {
++            inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlv;
++            inact_tlv->header.Type =
++                uap_cpu_to_le16(TLV_TYPE_AP_INACT_SLEEP_PARAM);
++            inact_tlv->header.Len =
++                uap_cpu_to_le16(sizeof(MrvlIEtypes_inact_sleep_param_t) -
++                                sizeof(MrvlIEtypesHeader_t));
++            inact_tlv->inactivity_to =
++                uap_cpu_to_le32(pm_cfg.inact_param.inactivity_to);
++            inact_tlv->min_awake =
++                uap_cpu_to_le32(pm_cfg.inact_param.min_awake);
++            inact_tlv->max_awake =
++                uap_cpu_to_le32(pm_cfg.inact_param.max_awake);
++            CmdSize += sizeof(MrvlIEtypes_inact_sleep_param_t);
++            tlv += sizeof(MrvlIEtypes_inact_sleep_param_t);
++        }
++    }
++    cmd->Size = uap_cpu_to_le16(CmdSize);
++    skb_put(skb, CmdSize + INTF_HEADER_LEN);
++    if (UAP_STATUS_SUCCESS !=
++        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) {
++        PRINTM(ERROR, "Fail to process cmd POWER_MODE\n");
++        ret = -EFAULT;
++        goto done;
++    }
++    if (!Adapter->CmdSize) {
++        PRINTM(ERROR, "Cmd Size is 0\n");
++        ret = -EFAULT;
++        goto done;
++    }
++    cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf;
++    cmd->Result = uap_le16_to_cpu(cmd->Result);
++    if (cmd->Result != UAP_STATUS_SUCCESS) {
++        PRINTM(ERROR, "HOST_CMD_APCMD_POWER_MODE fail=%x\n", cmd->Result);
++        ret = -EFAULT;
++        goto done;
++    }
++    if (pm_cfg.flags) {
++        Adapter->psmode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode);
++    } else {
++        pm_cfg.flags = PS_FLAG_PS_MODE;
++        pm_cfg.ps_mode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode);
++        tlv_buf_left =
++            cmd->Size - (sizeof(HostCmd_DS_POWER_MGMT_EXT) + S_DS_GEN);
++        tlvbuf =
++            (MrvlIEtypesHeader_t *) ((u8 *) & cmd->params.pm_cfg +
++                                     sizeof(HostCmd_DS_POWER_MGMT_EXT));
++        while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
++            tlv_type = uap_le16_to_cpu(tlvbuf->Type);
++            tlv_len = uap_le16_to_cpu(tlvbuf->Len);
++            switch (tlv_type) {
++            case TLV_TYPE_AP_SLEEP_PARAM:
++                sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlvbuf;
++                pm_cfg.flags |= PS_FLAG_SLEEP_PARAM;
++                pm_cfg.sleep_param.ctrl_bitmap =
++                    uap_le32_to_cpu(sleep_tlv->ctrl_bitmap);
++                pm_cfg.sleep_param.min_sleep =
++                    uap_le32_to_cpu(sleep_tlv->min_sleep);
++                pm_cfg.sleep_param.max_sleep =
++                    uap_le32_to_cpu(sleep_tlv->max_sleep);
++                break;
++            case TLV_TYPE_AP_INACT_SLEEP_PARAM:
++                inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlvbuf;
++                pm_cfg.flags |= PS_FLAG_INACT_SLEEP_PARAM;
++                pm_cfg.inact_param.inactivity_to =
++                    uap_le32_to_cpu(inact_tlv->inactivity_to);
++                pm_cfg.inact_param.min_awake =
++                    uap_le32_to_cpu(inact_tlv->min_awake);
++                pm_cfg.inact_param.max_awake =
++                    uap_le32_to_cpu(inact_tlv->max_awake);
++                break;
++            }
++            tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t);
++            tlvbuf =
++                (MrvlIEtypesHeader_t *) ((u8 *) tlvbuf + tlv_len +
++                                         sizeof(MrvlIEtypesHeader_t));
++        }
++        /* Copy to user */
++        if (copy_to_user(req->ifr_data, &pm_cfg, sizeof(ps_mgmt))) {
++            PRINTM(ERROR, "Copy to user failed!\n");
++            LEAVE();
++            return -EFAULT;
++        }
++    }
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function send bss_stop command to firmware
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
++ */
++static int
++uap_bss_stop(uap_private * priv)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u32 CmdSize;
++    HostCmd_DS_GEN *cmd;
++    uap_adapter *Adapter = priv->adapter;
++    struct sk_buff *skb;
++    ENTER();
++    if (Adapter->HardwareStatus != HWReady) {
++        PRINTM(ERROR, "uap_bss_stop:Hardware is not ready!\n");
++        ret = -EFAULT;
++        goto done;
++    }
++    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
++    if (!skb) {
++        PRINTM(ERROR, "No free skb\n");
++        ret = -ENOMEM;
++        goto done;
++    }
++    CmdSize = sizeof(HostCmd_DS_GEN);
++    cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
++    cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_BSS_STOP);
++    cmd->Size = uap_cpu_to_le16(CmdSize);
++    skb_put(skb, CmdSize + INTF_HEADER_LEN);
++    PRINTM(CMND, "APCMD_BSS_STOP\n");
++    if (UAP_STATUS_SUCCESS !=
++        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
++        PRINTM(ERROR, "Fail to process cmd BSS_STOP\n");
++        ret = -EFAULT;
++        goto done;
++    }
++  done:
++    LEAVE();
++    return ret;
++}
++
++/********************************************************
++              Global Functions
++********************************************************/
++/**
++ *  @brief This function send soft_reset command to firmware
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
++ */
++int
++uap_soft_reset(uap_private * priv)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u32 CmdSize;
++    HostCmd_DS_GEN *cmd;
++    uap_adapter *Adapter = priv->adapter;
++    struct sk_buff *skb;
++    ENTER();
++    ret = uap_bss_stop(priv);
++    if (ret != UAP_STATUS_SUCCESS)
++        goto done;
++    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
++    if (!skb) {
++        PRINTM(ERROR, "No free skb\n");
++        ret = -ENOMEM;
++        goto done;
++    }
++    CmdSize = sizeof(HostCmd_DS_GEN);
++    cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
++    cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SOFT_RESET);
++    cmd->Size = uap_cpu_to_le16(CmdSize);
++    skb_put(skb, CmdSize + INTF_HEADER_LEN);
++    PRINTM(CMND, "APCMD_SOFT_RESET\n");
++    if (UAP_STATUS_SUCCESS !=
++        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORSEND)) {
++        PRINTM(ERROR, "Fail to process cmd SOFT_RESET\n");
++        ret = -EFAULT;
++        goto done;
++    }
++    Adapter->SurpriseRemoved = TRUE;
++    /* delay to allow hardware complete reset */
++    os_sched_timeout(5);
++    if (priv->MediaConnected == TRUE) {
++        os_stop_queue(priv);
++        os_carrier_off(priv);
++        priv->MediaConnected = FALSE;
++    }
++    Adapter->CmdSize = 0;
++    Adapter->CmdWaitQWoken = TRUE;
++    wake_up_interruptible(&Adapter->cmdwait_q);
++    skb_queue_purge(&priv->adapter->tx_queue);
++    skb_queue_purge(&priv->adapter->cmd_queue);
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function processes received packet and forwards it
++ *  to kernel/upper layer
++ *
++ *  @param priv    A pointer to uap_private
++ *  @param skb     A pointer to skb which includes the received packet
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++uap_process_rx_packet(uap_private * priv, struct sk_buff *skb)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    RxPD *pRxPD;
++    ENTER();
++    priv->adapter->ps_state = PS_STATE_AWAKE;
++    pRxPD = (RxPD *) skb->data;
++    endian_convert_RxPD(pRxPD);
++    DBG_HEXDUMP(DAT_D, "Rx", skb->data, MIN(skb->len, DATA_DUMP_LEN));
++    skb_pull(skb, pRxPD->RxPktOffset);
++    priv->stats.rx_packets++;
++    priv->stats.rx_bytes += skb->len;
++    os_upload_rx_packet(priv, skb);
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function opens the network device
++ *
++ *  @param dev     A pointer to net_device structure
++ *  @return        UAP_STATUS_SUCCESS
++ */
++static int
++uap_open(struct net_device *dev)
++{
++    uap_private *priv = (uap_private *) (uap_private *) netdev_priv(dev);
++    uap_adapter *Adapter = priv->adapter;
++    int i = 0;
++
++    ENTER();
++
++    /* On some systems the device open handler will be called before HW ready. */
++    /* Use the following flag check and wait function to work around the issue. */
++    while ((Adapter->HardwareStatus != HWReady) &&
++           (i < MAX_WAIT_DEVICE_READY_COUNT)) {
++        i++;
++        os_sched_timeout(100);
++    }
++    if (i >= MAX_WAIT_DEVICE_READY_COUNT) {
++        PRINTM(FATAL, "HW not ready, uap_open() return failure\n");
++        LEAVE();
++        return UAP_STATUS_FAILURE;
++    }
++
++    if (MODULE_GET == 0)
++        return UAP_STATUS_FAILURE;
++
++    priv->open = TRUE;
++    if (priv->MediaConnected == TRUE) {
++        os_carrier_on(priv);
++        os_start_queue(priv);
++    } else {
++        os_stop_queue(priv);
++        os_carrier_off(priv);
++    }
++    LEAVE();
++    return UAP_STATUS_SUCCESS;
++}
++
++/**
++ *  @brief This function closes the network device
++ *
++ *  @param dev     A pointer to net_device structure
++ *  @return        UAP_STATUS_SUCCESS
++ */
++static int
++uap_close(struct net_device *dev)
++{
++    uap_private *priv = (uap_private *) netdev_priv(dev);
++
++    ENTER();
++    skb_queue_purge(&priv->adapter->tx_queue);
++    os_stop_queue(priv);
++    os_carrier_off(priv);
++
++    MODULE_PUT;
++    priv->open = FALSE;
++    LEAVE();
++    return UAP_STATUS_SUCCESS;
++}
++
++/**
++ *  @brief This function returns the network statistics
++ *
++ *  @param dev     A pointer to uap_private structure
++ *  @return        A pointer to net_device_stats structure
++ */
++static struct net_device_stats *
++uap_get_stats(struct net_device *dev)
++{
++    uap_private *priv = (uap_private *) netdev_priv(dev);
++
++    return &priv->stats;
++}
++
++/**
++ *  @brief This function sets the MAC address to firmware.
++ *
++ *  @param dev     A pointer to uap_private structure
++ *  @param addr    MAC address to set
++ *  @return        UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++uap_set_mac_address(struct net_device *dev, void *addr)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    uap_private *priv = (uap_private *) netdev_priv(dev);
++    struct sockaddr *pHwAddr = (struct sockaddr *) addr;
++    u32 CmdSize;
++    HostCmd_DS_COMMAND *cmd;
++    MrvlIEtypes_MacAddr_t *pMacAddrTlv;
++    uap_adapter *Adapter = priv->adapter;
++    struct sk_buff *skb;
++
++    ENTER();
++
++    /* Dump MAC address */
++    DBG_HEXDUMP(CMD_D, "Original MAC addr", dev->dev_addr, ETH_ALEN);
++    DBG_HEXDUMP(CMD_D, "New MAC addr", pHwAddr->sa_data, ETH_ALEN);
++    if (priv->open && (priv->MediaConnected == TRUE)) {
++        os_carrier_on(priv);
++        os_start_queue(priv);
++    }
++    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
++    if (!skb) {
++        PRINTM(ERROR, "No free skb\n");
++        LEAVE();
++        return -ENOMEM;
++    }
++    CmdSize =
++        S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t);
++    cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
++    cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
++    cmd->Size = uap_cpu_to_le16(CmdSize);
++    cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_SET);
++    pMacAddrTlv =
++        (MrvlIEtypes_MacAddr_t *) ((u8 *) cmd + S_DS_GEN +
++                                   sizeof(HostCmd_SYS_CONFIG));
++    pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID);
++    pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN);
++    memcpy(pMacAddrTlv->ApMacAddr, pHwAddr->sa_data, ETH_ALEN);
++    skb_put(skb, CmdSize + INTF_HEADER_LEN);
++    PRINTM(CMND, "set_mac_address\n");
++    if (UAP_STATUS_SUCCESS !=
++        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
++        PRINTM(ERROR, "Fail to set mac address\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    if (!Adapter->CmdSize) {
++        PRINTM(ERROR, "Cmd Size is 0\n");
++        LEAVE();
++        return -EFAULT;
++    }
++    cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf;
++    cmd->Result = uap_cpu_to_le16(cmd->Result);
++    if (cmd->Result != UAP_STATUS_SUCCESS) {
++        PRINTM(ERROR, "set mac addrress fail,cmd result=%x\n", cmd->Result);
++        ret = -EFAULT;
++    } else
++        memcpy(dev->dev_addr, pHwAddr->sa_data, ETH_ALEN);
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function handles the timeout of packet
++ *  transmission
++ *
++ *  @param dev     A pointer to net_device structure
++ *  @return        n/a
++ */
++static void
++uap_tx_timeout(struct net_device *dev)
++{
++    uap_private *priv = (uap_private *) netdev_priv(dev);
++
++    ENTER();
++
++    PRINTM(DATA, "Tx timeout\n");
++    UpdateTransStart(dev);
++    priv->num_tx_timeout++;
++    priv->adapter->IntCounter++;
++    wake_up_interruptible(&priv->MainThread.waitQ);
++
++    LEAVE();
++}
++
++/**
++ *  @brief This function handles packet transmission
++ *
++ *  @param skb     A pointer to sk_buff structure
++ *  @param dev     A pointer to net_device structure
++ *  @return        UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++uap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++    uap_private *priv = (uap_private *) netdev_priv(dev);
++    int ret = UAP_STATUS_SUCCESS;
++
++    ENTER();
++    PRINTM(DATA, "Data <= kernel\n");
++    DBG_HEXDUMP(DAT_D, "Tx", skb->data, MIN(skb->len, DATA_DUMP_LEN));
++    /* skb sanity check */
++    if (!skb->len || (skb->len > MRVDRV_MAXIMUM_ETH_PACKET_SIZE)) {
++        PRINTM(ERROR, "Tx Error: Bad skb length %d : %d\n", skb->len,
++               MRVDRV_MAXIMUM_ETH_PACKET_SIZE);
++        priv->stats.tx_dropped++;
++        kfree(skb);
++        goto done;
++    }
++    skb_queue_tail(&priv->adapter->tx_queue, skb);
++    wake_up_interruptible(&priv->MainThread.waitQ);
++    if (skb_queue_len(&priv->adapter->tx_queue) > TX_HIGH_WATERMARK) {
++        UpdateTransStart(dev);
++        os_stop_queue(priv);
++    }
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief ioctl function - entry point
++ *
++ *  @param dev      A pointer to net_device structure
++ *  @param req      A pointer to ifreq structure
++ *  @param cmd      command
++ *  @return         UAP_STATUS_SUCCESS--success, otherwise fail
++ */
++static int
++uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
++{
++    int ret = UAP_STATUS_SUCCESS;
++
++    ENTER();
++
++    PRINTM(CMND, "uap_do_ioctl: ioctl cmd = 0x%x\n", cmd);
++
++    switch (cmd) {
++    case UAPHOSTCMD:
++        ret = uap_hostcmd_ioctl(dev, req);
++        break;
++    case UAP_POWER_MODE:
++        ret = uap_power_mode_ioctl(dev, req);
++        break;
++    default:
++        ret = -EINVAL;
++        break;
++    }
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function handles events generated by firmware
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param payload A pointer to payload buffer
++ *  @param len           Length of the payload
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++uap_process_event(uap_private * priv, u8 * payload, uint len)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    uap_adapter *Adapter = priv->adapter;
++    struct sk_buff *skb = NULL;
++    struct nlmsghdr *nlh = NULL;
++    struct sock *sk = Adapter->nl_sk;
++    AP_Event *pEvent;
++
++    ENTER();
++    Adapter->ps_state = PS_STATE_AWAKE;
++    if (len > NL_MAX_PAYLOAD) {
++        PRINTM(ERROR, "event size is too big!!! len=%d\n", len);
++        ret = UAP_STATUS_FAILURE;
++        goto done;
++    }
++    pEvent = (AP_Event *) payload;
++    PRINTM(CMND, "Event: %d\n", pEvent->EventId);
++    switch (pEvent->EventId) {
++    case MICRO_AP_EV_ID_BSS_START:
++        memcpy(priv->uap_dev.netdev->dev_addr, pEvent->MacAddr, ETH_ALEN);
++        DBG_HEXDUMP(CMD_D, "BSS MAC addr", priv->uap_dev.netdev->dev_addr,
++                    ETH_ALEN);
++        break;
++    case MICRO_AP_EV_BSS_ACTIVE:
++        // carrier on
++        priv->MediaConnected = TRUE;
++        os_carrier_on(priv);
++        os_start_queue(priv);
++        break;
++    case MICRO_AP_EV_BSS_IDLE:
++        os_stop_queue(priv);
++        os_carrier_off(priv);
++        priv->MediaConnected = FALSE;
++        break;
++    case EVENT_PS_AWAKE:
++        PRINTM(CMND, "UAP: PS_AWAKE\n");
++        Adapter->ps_state = PS_STATE_AWAKE;
++        Adapter->WakeupTries = 0;
++        break;
++    case EVENT_PS_SLEEP:
++        PRINTM(CMND, "UAP: PS_SLEEP\n");
++        Adapter->ps_state = PS_STATE_PRE_SLEEP;
++        break;
++    default:
++        break;
++    }
++    if ((pEvent->EventId == EVENT_PS_AWAKE) ||
++        (pEvent->EventId == EVENT_PS_SLEEP))
++        goto done;
++    if (sk) {
++        /* Allocate skb */
++        if (!(skb = alloc_skb(NLMSG_SPACE(NL_MAX_PAYLOAD), GFP_ATOMIC))) {
++            PRINTM(ERROR, "Could not allocate skb for netlink.\n");
++            ret = UAP_STATUS_FAILURE;
++            goto done;
++        }
++        nlh = (struct nlmsghdr *) skb->data;
++        nlh->nlmsg_len = NLMSG_SPACE(len);
++
++        /* From kernel */
++        nlh->nlmsg_pid = 0;
++        nlh->nlmsg_flags = 0;
++
++        /* Data */
++        skb_put(skb, nlh->nlmsg_len);
++        memcpy(NLMSG_DATA(nlh), payload, len);
++
++        /* From Kernel */
++        NETLINK_CB(skb).portid = 0;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
++        /* Multicast message */
++        NETLINK_CB(skb).dst_pid = 0;
++#endif
++
++        /* Multicast group number */
++        NETLINK_CB(skb).dst_group = NL_MULTICAST_GROUP;
++
++        /* Send message */
++        netlink_broadcast(sk, skb, 0, NL_MULTICAST_GROUP, GFP_KERNEL);
++
++        ret = UAP_STATUS_SUCCESS;
++    } else {
++        PRINTM(ERROR, "Could not send event through NETLINK. Link down.\n");
++        ret = UAP_STATUS_FAILURE;
++    }
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function handles the interrupt. it will change PS
++ *  state if applicable. it will wake up main_thread to handle
++ *  the interrupt event as well.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return        n/a
++ */
++void
++uap_interrupt(uap_private * priv)
++{
++    ENTER();
++    priv->adapter->IntCounter++;
++    priv->adapter->WakeupTries = 0;
++    PRINTM(INFO, "*\n");
++    wake_up_interruptible(&priv->MainThread.waitQ);
++
++    LEAVE();
++
++}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
++/** Network device handlers */
++static const struct net_device_ops uap_netdev_ops = {
++    .ndo_open = uap_open,
++    .ndo_start_xmit = uap_hard_start_xmit,
++    .ndo_stop = uap_close,
++    .ndo_do_ioctl = uap_do_ioctl,
++    .ndo_set_mac_address = uap_set_mac_address,
++    .ndo_tx_timeout = uap_tx_timeout,
++    .ndo_get_stats = uap_get_stats,
++};
++#endif
++
++/**
++ * @brief This function adds the card. it will probe the
++ * card, allocate the uap_priv and initialize the device.
++ *
++ *  @param card    A pointer to card
++ *  @return        A pointer to uap_private structure
++ */
++uap_private *
++uap_add_card(void *card)
++{
++    struct net_device *dev = NULL;
++    uap_private *priv = NULL;
++
++    ENTER();
++
++    if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
++        goto exit_sem_err;
++
++    /* Allocate an Ethernet device */
++    if (!(dev = alloc_etherdev(sizeof(uap_private)))) {
++        PRINTM(FATAL, "Init ethernet device failed!\n");
++        goto error;
++    }
++    priv = (uap_private *) netdev_priv(dev);
++
++    /* Allocate name */
++    if (dev_alloc_name(dev, "uap%d") < 0) {
++        PRINTM(ERROR, "Could not allocate device name!\n");
++        goto error;
++    }
++
++    /* Allocate buffer for uap_adapter */
++    if (!(priv->adapter = kmalloc(sizeof(uap_adapter), GFP_KERNEL))) {
++        PRINTM(FATAL, "Allocate buffer for uap_adapter failed!\n");
++        goto error;
++    }
++    memset(priv->adapter, 0, sizeof(uap_adapter));
++
++    priv->uap_dev.netdev = dev;
++    priv->uap_dev.card = card;
++    priv->MediaConnected = FALSE;
++    uappriv = priv;
++    ((struct sdio_mmc_card *) card)->priv = priv;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
++    SET_MODULE_OWNER(dev);
++#endif
++
++    /* Setup the OS Interface to our functions */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
++    dev->open = uap_open;
++    dev->stop = uap_close;
++    dev->hard_start_xmit = uap_hard_start_xmit;
++    dev->tx_timeout = uap_tx_timeout;
++    dev->get_stats = uap_get_stats;
++    dev->do_ioctl = uap_do_ioctl;
++    dev->set_mac_address = uap_set_mac_address;
++    dev->set_multicast_list = uap_set_multicast_list;
++#else
++    dev->netdev_ops = &uap_netdev_ops;
++#endif
++    dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT;
++    dev->hard_header_len += sizeof(TxPD) + INTF_HEADER_LEN;
++    dev->hard_header_len += HEADER_ALIGNMENT;
++#define NETIF_F_DYNALLOC 16
++    dev->features |= NETIF_F_DYNALLOC;
++    dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
++
++    /* Init SW */
++    if (uap_init_sw(priv)) {
++        PRINTM(FATAL, "Software Init Failed\n");
++        goto error;
++    }
++
++    PRINTM(INFO, "Starting kthread...\n");
++    priv->MainThread.priv = priv;
++    spin_lock_init(&priv->driver_lock);
++    uap_create_thread(uap_service_main_thread, &priv->MainThread,
++                      "uap_main_service");
++    while (priv->MainThread.pid == 0) {
++        os_sched_timeout(2);
++    }
++
++    /* Register the device */
++    if (sbi_register_dev(priv) < 0) {
++        PRINTM(FATAL, "Failed to register uap device!\n");
++        goto err_registerdev;
++    }
++#ifdef FW_DNLD_NEEDED
++    SET_NETDEV_DEV(dev, priv->hotplug_device);
++#endif
++
++    /* Init FW and HW */
++    if (uap_init_fw(priv)) {
++        PRINTM(FATAL, "Firmware Init Failed\n");
++        goto err_init_fw;
++    }
++
++    priv->uap_dev.cmd_sent = FALSE;
++    priv->uap_dev.data_sent = FALSE;
++
++    /* Get mac address from firmware */
++    if (uap_get_mac_address(priv)) {
++        PRINTM(FATAL, "Fail to get mac address\n");
++        goto err_init_fw;
++    }
++    /* Register network device */
++    if (register_netdev(dev)) {
++        printk(KERN_ERR "Cannot register network device!\n");
++        goto err_init_fw;
++    }
++#ifdef CONFIG_PROC_FS
++    uap_proc_entry(priv, dev);
++    uap_debug_entry(priv, dev);
++#endif /* CPNFIG_PROC_FS */
++    OS_REL_SEMAPHORE(&AddRemoveCardSem);
++
++    LEAVE();
++    return priv;
++  err_init_fw:
++    sbi_unregister_dev(priv);
++  err_registerdev:
++    ((struct sdio_mmc_card *) card)->priv = NULL;
++    /* Stop the thread servicing the interrupts */
++    priv->adapter->SurpriseRemoved = TRUE;
++    wake_up_interruptible(&priv->MainThread.waitQ);
++    while (priv->MainThread.pid) {
++        os_sched_timeout(1);
++    }
++  error:
++    if (dev) {
++        if (dev->reg_state == NETREG_REGISTERED)
++            unregister_netdev(dev);
++        if (priv->adapter)
++            uap_free_adapter(priv);
++        free_netdev(dev);
++        uappriv = NULL;
++    }
++    OS_REL_SEMAPHORE(&AddRemoveCardSem);
++  exit_sem_err:
++    LEAVE();
++    return NULL;
++}
++
++/**
++ *  @brief This function removes the card.
++ *
++ *  @param card    A pointer to card
++ *  @return        UAP_STATUS_SUCCESS
++ */
++int
++uap_remove_card(void *card)
++{
++    uap_private *priv = uappriv;
++    uap_adapter *Adapter;
++    struct net_device *dev;
++
++    ENTER();
++
++    if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
++        goto exit_sem_err;
++
++    if (!priv || !(Adapter = priv->adapter)) {
++        goto exit_remove;
++    }
++    Adapter->SurpriseRemoved = TRUE;
++    if (Adapter->cmd_pending == TRUE) {
++        /* Wake up cmd Q */
++        Adapter->CmdWaitQWoken = TRUE;
++        wake_up_interruptible(&Adapter->cmdwait_q);
++    }
++    dev = priv->uap_dev.netdev;
++    if (priv->MediaConnected == TRUE) {
++        os_stop_queue(priv);
++        os_carrier_off(priv);
++        priv->MediaConnected = FALSE;
++    }
++    Adapter->CmdSize = 0;
++    Adapter->CmdWaitQWoken = TRUE;
++    wake_up_interruptible(&Adapter->cmdwait_q);
++    skb_queue_purge(&priv->adapter->tx_queue);
++    skb_queue_purge(&priv->adapter->cmd_queue);
++
++    /* Disable interrupts on the card */
++    sbi_disable_host_int(priv);
++    PRINTM(INFO, "netdev_finish_unregister: %s%s.\n", dev->name,
++           (dev->features & NETIF_F_DYNALLOC) ? "" : ", old style");
++    unregister_netdev(dev);
++    PRINTM(INFO, "Unregister finish\n");
++    wake_up_interruptible(&priv->MainThread.waitQ);
++    while (priv->MainThread.pid) {
++        os_sched_timeout(1);
++    }
++
++    if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) {
++        sock_release((Adapter->nl_sk)->sk_socket);
++        Adapter->nl_sk = NULL;
++    }
++#ifdef CONFIG_PROC_FS
++    uap_debug_remove(priv);
++    uap_proc_remove(priv);
++#endif
++    sbi_unregister_dev(priv);
++    PRINTM(INFO, "Free Adapter\n");
++    uap_free_adapter(priv);
++    priv->uap_dev.netdev = NULL;
++    free_netdev(dev);
++    uappriv = NULL;
++
++  exit_remove:
++    OS_REL_SEMAPHORE(&AddRemoveCardSem);
++  exit_sem_err:
++    LEAVE();
++    return UAP_STATUS_SUCCESS;
++}
++
++/**
++ *  @brief This function initializes module.
++ *
++ *  @return    UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int __init
++uap_init_module(void)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    ENTER();
++
++    OS_INIT_SEMAPHORE(&AddRemoveCardSem);
++    ret = sbi_register();
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function cleans module
++ *
++ *  @return        n/a
++ */
++static void __exit
++uap_cleanup_module(void)
++{
++    ENTER();
++
++    if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
++        goto exit_sem_err;
++
++    if ((uappriv) && (uappriv->adapter)) {
++        uap_func_shutdown(uappriv);
++    }
++    OS_REL_SEMAPHORE(&AddRemoveCardSem);
++  exit_sem_err:
++    sbi_unregister();
++    LEAVE();
++}
++
++module_init(uap_init_module);
++module_exit(uap_cleanup_module);
++module_param(helper_name, charp, 0);
++MODULE_PARM_DESC(helper_name, "Helper name");
++module_param(fw_name, charp, 0);
++MODULE_PARM_DESC(fw_name, "Firmware name");
++
++MODULE_DESCRIPTION("M-UAP Driver");
++MODULE_AUTHOR("Marvell International Ltd.");
++MODULE_VERSION(DRIVER_VERSION);
++MODULE_LICENSE("GPL");
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_proc.c backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_proc.c
+--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_proc.c        1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_proc.c    2014-12-29 20:37:43.952431125 +0100
+@@ -0,0 +1,258 @@
++/** @file uap_proc.c
++  * @brief This file contains functions for proc file.
++  *
++  * Copyright (C) 2008-2009, Marvell International Ltd.
++  *
++  * This software file (the "File") is distributed by Marvell International
++  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
++  * (the "License").  You may use, redistribute and/or modify this File in
++  * accordance with the terms and conditions of the License, a copy of which
++  * is available along with the File in the gpl.txt file or by writing to
++  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
++  *
++  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
++  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
++  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
++  * this warranty disclaimer.
++  *
++  */
++#ifdef CONFIG_PROC_FS
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include "uap_headers.h"
++
++/** /proc directory root */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++#define PROC_DIR NULL
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
++#define PROC_DIR &proc_root
++#else
++#define PROC_DIR proc_net
++#endif
++
++/********************************************************
++              Local Variables
++********************************************************/
++
++/********************************************************
++              Global Variables
++********************************************************/
++
++/********************************************************
++              Local Functions
++********************************************************/
++
++static int uap_info_proc_show(struct seq_file *s, void *data) {
++    int i;
++    struct net_device *netdev = (struct net_device*)s->private;
++    struct netdev_hw_addr *ha;
++    uap_private *priv = (uap_private *) netdev_priv(netdev);
++
++    seq_printf(s, "driver_name = " "\"uap\"\n");
++    seq_printf(s, "driver_version = %s-(FP%s)", DRIVER_VERSION, FPNUM);
++    seq_printf(s, "\nInterfaceName=\"%s\"\n", netdev->name);
++
++    seq_printf(s, "State=\"%s\"\n",
++                 ((priv->MediaConnected ==
++                   FALSE) ? "Disconnected" : "Connected"));
++    seq_printf(s, "MACAddress=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
++                 netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
++                 netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
++    i = 0;
++    netdev_for_each_mc_addr(ha, netdev) {
++        ++i;
++    }
++    seq_printf(s, "MCCount=\"%d\"\n", i);
++
++    /*
++     * Put out the multicast list
++     */
++    i = 0;
++    netdev_for_each_mc_addr(ha, netdev) {
++        seq_printf(s,
++                     "MCAddr[%d]=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
++                     i++,
++                     ha->addr[0], ha->addr[1],
++                     ha->addr[2], ha->addr[3],
++                     ha->addr[4], ha->addr[5]);
++    }
++
++    seq_printf(s, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
++    seq_printf(s, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
++    seq_printf(s, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
++    seq_printf(s, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
++    seq_printf(s, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
++    seq_printf(s, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
++    seq_printf(s, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
++    seq_printf(s, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
++    seq_printf(s, "num_tx_timeout = %u\n", priv->num_tx_timeout);
++    seq_printf(s, "carrier %s\n",
++                 ((netif_carrier_ok(priv->uap_dev.netdev)) ? "on" : "off"));
++    seq_printf(s, "tx queue %s\n",
++                 ((netif_queue_stopped(priv->uap_dev.netdev)) ? "stopped" :
++                  "started"));
++
++    return 0;
++}
++
++static int uap_info_proc_open(struct inode *inode, struct file *file) {
++      return single_open(file, uap_info_proc_show, PDE_DATA(inode));
++}
++
++static int uap_hwstatus_proc_show(struct seq_file *s, void *data) {
++    struct net_device *netdev = (struct net_device*)s->private;
++    uap_private *priv = (uap_private *) netdev_priv(netdev);
++
++    MODULE_GET;
++    seq_printf(s, "%d\n", priv->adapter->HardwareStatus);
++    MODULE_PUT;
++
++    return 0;
++}
++
++static int uap_hwstatus_proc_open(struct inode *inode, struct file *file) {
++      return single_open(file, uap_hwstatus_proc_show, PDE_DATA(inode));
++}
++
++static ssize_t uap_hwstatus_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *data) {
++      struct net_device *netdev = (struct net_device *)PDE_DATA(file_inode(file));
++      uap_private *priv = (uap_private *) netdev_priv(netdev);
++
++      int hwstatus;
++      char value[10];
++
++      if (count > sizeof(value))
++              return count;
++
++      if (copy_from_user(&value, buffer, count))
++              return -EFAULT;
++
++      hwstatus = string_to_number(value);
++      switch (hwstatus) {
++      case HWReset:
++              PRINTM(MSG, "reset hw\n");
++              uap_soft_reset(priv);
++              priv->adapter->HardwareStatus = HWReset;
++              break;
++      default:
++              break;
++      }
++
++      MODULE_PUT;
++      return count;
++}
++
++static const struct file_operations uap_info_proc_fops = {
++      .owner   = THIS_MODULE,
++      .open    = uap_info_proc_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = single_release,
++};
++
++static const struct file_operations uap_hwstatus_proc_fops = {
++      .owner   = THIS_MODULE,
++      .open    = uap_hwstatus_proc_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = single_release,
++      .write   = uap_hwstatus_proc_write,
++};
++
++/********************************************************
++              Global Functions
++********************************************************/
++/**
++ *  @brief create uap proc file
++ *
++ *  @param priv          pointer uap_private
++ *  @param dev     pointer net_device
++ *  @return      N/A
++ */
++void
++uap_proc_entry(uap_private * priv, struct net_device *dev)
++{
++    PRINTM(INFO, "Creating Proc Interface\n");
++    /* Check if uap directory already exists */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
++    struct proc_dir_entry *r = PROC_DIR;
++
++    for (r = r->subdir; r; r = r->next) {
++        if (r->namelen && !strcmp("uap", r->name)) {
++            /* Directory exists */
++            PRINTM(WARN, "proc directory already exists!\n");
++            priv->proc_uap = r;
++            break;
++        }
++    }
++#endif
++    if (!priv->proc_uap) {
++        priv->proc_uap = proc_mkdir("uap", PROC_DIR);
++        if (!priv->proc_uap)
++            return;
++    }
++    priv->proc_entry = proc_mkdir(dev->name, priv->proc_uap);
++
++    if (priv->proc_entry) {
++      proc_create_data("info", 0644, priv->proc_entry, &uap_info_proc_fops, dev);
++      proc_create_data("hwinfo", 0644, priv->proc_entry, &uap_hwstatus_proc_fops, dev);
++    }
++}
++
++/**
++ *  @brief remove proc file
++ *
++ *  @param priv          pointer uap_private
++ *  @return      N/A
++ */
++void
++uap_proc_remove(uap_private * priv)
++{
++    if (priv->proc_uap) {
++        if (priv->proc_entry) {
++            remove_proc_entry("info", priv->proc_entry);
++            remove_proc_entry("hwstatus", priv->proc_entry);
++        }
++        remove_proc_entry(priv->uap_dev.netdev->name, priv->proc_uap);
++    }
++}
++
++/**
++ *  @brief convert string to number
++ *
++ *  @param s     pointer to numbered string
++ *  @return      converted number from string s
++ */
++int
++string_to_number(char *s)
++{
++    int r = 0;
++    int base = 0;
++    int pn = 1;
++
++    if (strncmp(s, "-", 1) == 0) {
++        pn = -1;
++        s++;
++    }
++    if ((strncmp(s, "0x", 2) == 0) || (strncmp(s, "0X", 2) == 0)) {
++        base = 16;
++        s += 2;
++    } else
++        base = 10;
++
++    for (s = s; *s != 0; s++) {
++        if ((*s >= '0') && (*s <= '9'))
++            r = (r * base) + (*s - '0');
++        else if ((*s >= 'A') && (*s <= 'F'))
++            r = (r * base) + (*s - 'A' + 10);
++        else if ((*s >= 'a') && (*s <= 'f'))
++            r = (r * base) + (*s - 'a' + 10);
++        else
++            break;
++    }
++
++    return (r * pn);
++}
++
++#endif
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c
+--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c    1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c        2014-12-29 20:37:43.955764567 +0100
+@@ -0,0 +1,1428 @@
++/** @file uap_sdio_mmc.c
++ *  @brief This file contains SDIO IF (interface) module
++ *  related functions.
++ *
++ * Copyright (C) 2007-2009, Marvell International Ltd.
++ *
++ * This software file (the "File") is distributed by Marvell International
++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
++ * (the "License").  You may use, redistribute and/or modify this File in
++ * accordance with the terms and conditions of the License, a copy of which
++ * is available along with the File in the gpl.txt file or by writing to
++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
++ *
++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
++ * this warranty disclaimer.
++ *
++ */
++/****************************************************
++Change log:
++****************************************************/
++
++#include      "uap_sdio_mmc.h"
++
++#include <linux/firmware.h>
++
++/** define SDIO block size */
++/* We support up to 480-byte block size due to FW buffer limitation. */
++#define SD_BLOCK_SIZE         256
++
++/** define allocated buffer size */
++#define ALLOC_BUF_SIZE                (((MAX(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, \
++                                      MRVDRV_SIZE_OF_CMD_BUFFER) + INTF_HEADER_LEN \
++                                      + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE) * SD_BLOCK_SIZE)
++
++/** Max retry number of CMD53 write */
++#define MAX_WRITE_IOMEM_RETRY 2
++
++/********************************************************
++              Local Variables
++********************************************************/
++
++/** SDIO Rx unit */
++static u8 sdio_rx_unit = 0;
++
++/**Interrupt status */
++static u8 sd_ireg = 0;
++/********************************************************
++              Global Variables
++********************************************************/
++extern u8 *helper_name;
++extern u8 *fw_name;
++/** Default helper name */
++#define DEFAULT_HELPER_NAME "mrvl/helper_sd.bin"
++/** Default firmware name */
++#define DEFAULT_FW_NAME "mrvl/sd8688_ap.bin"
++
++/********************************************************
++              Local Functions
++********************************************************/
++/**
++ *  @brief This function reads the IO register.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param reg           register to be read
++ *  @param dat           A pointer to variable that keeps returned value
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++sbi_read_ioreg(uap_private * priv, u32 reg, u8 * dat)
++{
++    struct sdio_mmc_card *card;
++    int ret = UAP_STATUS_FAILURE;
++
++    ENTER();
++
++    card = priv->uap_dev.card;
++    if (!card || !card->func) {
++        PRINTM(ERROR, "sbi_read_ioreg(): card or function is NULL!\n");
++        goto done;
++    }
++
++    *dat = sdio_readb(card->func, reg, &ret);
++    if (ret) {
++        PRINTM(ERROR, "sbi_read_ioreg(): sdio_readb failed! ret=%d\n", ret);
++        goto done;
++    }
++
++    PRINTM(INFO, "sbi_read_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv,
++           card->func->num, reg, *dat);
++
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function writes the IO register.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param reg           register to be written
++ *  @param dat           the value to be written
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++sbi_write_ioreg(uap_private * priv, u32 reg, u8 dat)
++{
++    struct sdio_mmc_card *card;
++    int ret = UAP_STATUS_FAILURE;
++
++    ENTER();
++
++    card = priv->uap_dev.card;
++    if (!card || !card->func) {
++        PRINTM(ERROR, "sbi_write_ioreg(): card or function is NULL!\n");
++        goto done;
++    }
++
++    PRINTM(INFO, "sbi_write_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv,
++           card->func->num, reg, dat);
++
++    sdio_writeb(card->func, dat, reg, &ret);
++    if (ret) {
++        PRINTM(ERROR, "sbi_write_ioreg(): sdio_readb failed! ret=%d\n", ret);
++        goto done;
++    }
++
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function get rx_unit value
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++sd_get_rx_unit(uap_private * priv)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u8 reg;
++
++    ENTER();
++
++    ret = sbi_read_ioreg(priv, CARD_RX_UNIT_REG, &reg);
++    if (ret == UAP_STATUS_SUCCESS)
++        sdio_rx_unit = reg;
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function reads rx length
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param dat           A pointer to keep returned data
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++sd_read_rx_len(uap_private * priv, u16 * dat)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u8 reg;
++
++    ENTER();
++
++    ret = sbi_read_ioreg(priv, CARD_RX_LEN_REG, &reg);
++    if (ret == UAP_STATUS_SUCCESS)
++        *dat = (u16) reg << sdio_rx_unit;
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function reads fw status registers
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param dat           A pointer to keep returned data
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++sd_read_firmware_status(uap_private * priv, u16 * dat)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u8 fws0;
++    u8 fws1;
++
++    ENTER();
++
++    ret = sbi_read_ioreg(priv, CARD_FW_STATUS0_REG, &fws0);
++    if (ret < 0) {
++        LEAVE();
++        return UAP_STATUS_FAILURE;
++    }
++
++    ret = sbi_read_ioreg(priv, CARD_FW_STATUS1_REG, &fws1);
++    if (ret < 0) {
++        LEAVE();
++        return UAP_STATUS_FAILURE;
++    }
++
++    *dat = (((u16) fws1) << 8) | fws0;
++
++    LEAVE();
++    return UAP_STATUS_SUCCESS;
++}
++
++/**
++ *  @brief This function polls the card status register.
++ *
++ *  @param priv       A pointer to uap_private structure
++ *  @param bits       the bit mask
++ *  @return           UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++mv_sdio_poll_card_status(uap_private * priv, u8 bits)
++{
++    int tries;
++    u8 cs;
++
++    ENTER();
++
++    for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
++        if (sbi_read_ioreg(priv, CARD_STATUS_REG, &cs) < 0)
++            break;
++        else if ((cs & bits) == bits) {
++            LEAVE();
++            return UAP_STATUS_SUCCESS;
++        }
++        udelay(10);
++    }
++
++    PRINTM(WARN, "mv_sdio_poll_card_status failed, tries = %d\n", tries);
++
++    LEAVE();
++    return UAP_STATUS_FAILURE;
++}
++
++/**
++ *  @brief This function set the sdio bus width.
++ *
++ *  @param priv       A pointer to uap_private structure
++ *  @param mode       1--1 bit mode, 4--4 bit mode
++ *  @return           UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++#if 0
++static int
++sdio_set_bus_width(uap_private * priv, u8 mode)
++{
++    ENTER();
++    LEAVE();
++    return UAP_STATUS_SUCCESS;
++}
++#endif
++
++/**
++ *  @brief This function reads data from the card.
++ *
++ *  @param priv       A pointer to uap_private structure
++ *  @return           UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++sd_card_to_host(uap_private * priv)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u16 buf_len = 0;
++    int buf_block_len;
++    int blksz;
++    struct sk_buff *skb = NULL;
++    u16 type;
++    u8 *payload = NULL;
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++
++    ENTER();
++
++    if (!card || !card->func) {
++        PRINTM(ERROR, "card or function is NULL!\n");
++        ret = UAP_STATUS_FAILURE;
++        goto exit;
++    }
++
++    /* Read the length of data to be transferred */
++    ret = sd_read_rx_len(priv, &buf_len);
++    if (ret < 0) {
++        PRINTM(ERROR, "card_to_host, read scratch reg failed\n");
++        ret = UAP_STATUS_FAILURE;
++        goto exit;
++    }
++
++    /* Allocate buffer */
++    blksz = SD_BLOCK_SIZE;
++    buf_block_len = (buf_len + blksz - 1) / blksz;
++    if (buf_len <= INTF_HEADER_LEN || (buf_block_len * blksz) > ALLOC_BUF_SIZE) {
++        PRINTM(ERROR, "card_to_host, invalid packet length: %d\n", buf_len);
++        ret = UAP_STATUS_FAILURE;
++        goto exit;
++    }
++#ifdef PXA3XX_DMA_ALIGN
++    skb = dev_alloc_skb(buf_block_len * blksz + PXA3XX_DMA_ALIGNMENT);
++#else
++    skb = dev_alloc_skb(buf_block_len * blksz);
++#endif
++    if (skb == NULL) {
++        PRINTM(WARN, "No free skb\n");
++        goto exit;
++    }
++#ifdef PXA3XX_DMA_ALIGN
++    if ((u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)) {
++        skb_put(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1));
++        skb_pull(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1));
++    }
++#endif /* PXA3XX_DMA_ALIGN */
++
++    payload = skb->tail;
++    ret = sdio_readsb(card->func, payload, priv->uap_dev.ioport,
++                      buf_block_len * blksz);
++    if (ret < 0) {
++        PRINTM(ERROR, "card_to_host, read iomem failed: %d\n", ret);
++        ret = UAP_STATUS_FAILURE;
++        goto exit;
++    }
++    HEXDUMP("SDIO Blk Rd", payload, blksz * buf_block_len);
++    /*
++     * This is SDIO specific header
++     *  u16 length,
++     *  u16 type (MV_TYPE_DAT = 0, MV_TYPE_CMD = 1, MV_TYPE_EVENT = 3)
++     */
++    buf_len = uap_le16_to_cpu(*(u16 *) & payload[0]);
++    type = uap_le16_to_cpu(*(u16 *) & payload[2]);
++    switch (type) {
++    case MV_TYPE_EVENT:
++        skb_put(skb, buf_len);
++        skb_pull(skb, INTF_HEADER_LEN);
++        uap_process_event(priv, skb->data, skb->len);
++        kfree_skb(skb);
++        skb = NULL;
++        break;
++    case MV_TYPE_CMD:
++        skb_put(skb, buf_len);
++        skb_pull(skb, INTF_HEADER_LEN);
++        priv->adapter->cmd_pending = FALSE;
++        if (priv->adapter->cmd_wait_option ==
++            HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM) {
++            priv->adapter->cmd_wait_option = FALSE;
++            uap_process_sleep_confirm_resp(priv, skb->data, skb->len);
++        } else if (priv->adapter->cmd_wait_option) {
++            memcpy(priv->adapter->CmdBuf, skb->data, skb->len);
++            priv->adapter->CmdSize = skb->len;
++            priv->adapter->cmd_wait_option = FALSE;
++            priv->adapter->CmdWaitQWoken = TRUE;
++            wake_up_interruptible(&priv->adapter->cmdwait_q);
++        }
++        kfree_skb(skb);
++        skb = NULL;
++        break;
++    case MV_TYPE_DAT:
++        skb_put(skb, buf_len);
++        skb_pull(skb, INTF_HEADER_LEN);
++        uap_process_rx_packet(priv, skb);
++        break;
++    default:
++        priv->stats.rx_errors++;
++        priv->stats.rx_dropped++;
++        /* Driver specified event and command resp should be handle here */
++        PRINTM(INFO, "Unknown PKT type:%d\n", type);
++        kfree_skb(skb);
++        skb = NULL;
++        break;
++    }
++  exit:
++    if (ret) {
++        if (skb)
++            kfree_skb(skb);
++    }
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function enables the host interrupts mask
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param mask          the interrupt mask
++ *  @return      UAP_STATUS_SUCCESS
++ */
++static int
++enable_host_int_mask(uap_private * priv, u8 mask)
++{
++    int ret = UAP_STATUS_SUCCESS;
++
++    ENTER();
++
++    /* Simply write the mask to the register */
++    ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, mask);
++
++    if (ret) {
++        PRINTM(WARN, "Unable to enable the host interrupt!\n");
++        ret = UAP_STATUS_FAILURE;
++    }
++
++    LEAVE();
++    return ret;
++}
++
++/**  @brief This function disables the host interrupts mask.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param mask          the interrupt mask
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++disable_host_int_mask(uap_private * priv, u8 mask)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u8 host_int_mask;
++
++    ENTER();
++
++    /* Read back the host_int_mask register */
++    ret = sbi_read_ioreg(priv, HOST_INT_MASK_REG, &host_int_mask);
++    if (ret) {
++        ret = UAP_STATUS_FAILURE;
++        goto done;
++    }
++
++    /* Update with the mask and write back to the register */
++    host_int_mask &= ~mask;
++    ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, host_int_mask);
++    if (ret < 0) {
++        PRINTM(WARN, "Unable to diable the host interrupt!\n");
++        ret = UAP_STATUS_FAILURE;
++        goto done;
++    }
++
++  done:
++    LEAVE();
++    return ret;
++}
++
++/********************************************************
++              Global Functions
++********************************************************/
++
++/**
++ *  @brief This function handles the interrupt.
++ *
++ *  @param func          A pointer to sdio_func structure.
++ *  @return      n/a
++ */
++static void
++sbi_interrupt(struct sdio_func *func)
++{
++    struct sdio_mmc_card *card;
++    uap_private *priv;
++    u8 ireg = 0;
++    int ret = UAP_STATUS_SUCCESS;
++
++    ENTER();
++
++    card = sdio_get_drvdata(func);
++    if (!card || !card->priv) {
++        PRINTM(MSG, "%s: sbi_interrupt(%p) card or priv is NULL, card=%p\n",
++               __FUNCTION__, func, card);
++        LEAVE();
++        return;
++    }
++    priv = card->priv;
++#ifdef FW_WAKEUP_TIME
++    if ((priv->adapter->wt_pwrup_sending != 0L) &&
++        (priv->adapter->wt_int == 0L))
++        priv->adapter->wt_int = get_utimeofday();
++#endif
++
++    ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
++    if (ret) {
++        PRINTM(WARN, "sdio_read_ioreg: read int status register failed\n");
++        goto done;
++    }
++    if (ireg != 0) {
++        /*
++         * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
++         * Clear the interrupt status register and re-enable the interrupt
++         */
++        PRINTM(INFO, "sdio_ireg = 0x%x\n", ireg);
++        sdio_writeb(card->func,
++                    ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS),
++                    HOST_INTSTATUS_REG, &ret);
++        if (ret) {
++            PRINTM(WARN,
++                   "sdio_write_ioreg: clear int status register failed\n");
++            goto done;
++        }
++    }
++    OS_INT_DISABLE;
++    sd_ireg |= ireg;
++    OS_INT_RESTORE;
++
++    uap_interrupt(priv);
++  done:
++    LEAVE();
++}
++
++/**
++ *  @brief This function probe the card
++ *
++ *  @param func    A pointer to sdio_func structure
++ *  @param id    A pointer to structure sd_device_id
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++static int
++uap_probe(struct sdio_func *func, const struct sdio_device_id *id)
++{
++    int ret = UAP_STATUS_FAILURE;
++    struct sdio_mmc_card *card = NULL;
++
++    ENTER();
++
++    PRINTM(MSG, "%s: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
++           __FUNCTION__, func->vendor, func->device, func->class, func->num);
++
++    card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
++    if (!card) {
++        ret = -ENOMEM;
++        goto done;
++    }
++
++    card->func = func;
++
++    if (!uap_add_card(card)) {
++        PRINTM(ERROR, "%s: uap_add_callback failed\n", __FUNCTION__);
++        kfree(card);
++        ret = UAP_STATUS_FAILURE;
++        goto done;
++    }
++
++    ret = UAP_STATUS_SUCCESS;
++
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function removes the card
++ *
++ *  @param func    A pointer to sdio_func structure
++ *  @return        N/A
++ */
++static void
++uap_remove(struct sdio_func *func)
++{
++    struct sdio_mmc_card *card;
++
++    ENTER();
++
++    if (func) {
++        card = sdio_get_drvdata(func);
++        if (card) {
++            uap_remove_card(card);
++            kfree(card);
++        }
++    }
++
++    LEAVE();
++}
++
++#ifdef CONFIG_PM
++/**
++ *  @brief This function handles client driver suspend
++ *
++ *  @param func    A pointer to sdio_func structure
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++uap_suspend(struct sdio_func *func)
++{
++    ENTER();
++    LEAVE();
++    return 0;
++}
++
++/**
++ *  @brief This function handles client driver resume
++ *
++ *  @param func    A pointer to sdio_func structure
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++uap_resume(struct sdio_func *func)
++{
++    ENTER();
++    LEAVE();
++    return 0;
++}
++#endif
++
++/** Device ID for SD8688 */
++#define  SD_DEVICE_ID_8688_UAP 0x9104
++/** UAP IDs */
++static const struct sdio_device_id uap_ids[] = {
++    {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SD_DEVICE_ID_8688_UAP)},
++    {},
++};
++
++MODULE_DEVICE_TABLE(sdio, uap_ids);
++
++static struct sdio_driver uap_sdio = {
++    .name = "uap_sdio",
++    .id_table = uap_ids,
++    .probe = uap_probe,
++    .remove = uap_remove,
++#ifdef CONFIG_PM
++/*    .suspend        = uap_suspend, */
++/*    .resume = uap_resume, */
++#endif
++
++};
++
++/**
++ *  @brief This function registers the IF module in bus driver.
++ *
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int __init
++sbi_register()
++{
++    int ret = UAP_STATUS_SUCCESS;
++
++    ENTER();
++
++    /* SDIO Driver Registration */
++    if (sdio_register_driver(&uap_sdio) != 0) {
++        PRINTM(FATAL, "SDIO Driver Registration Failed \n");
++        ret = UAP_STATUS_FAILURE;
++    }
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function de-registers the IF module in bus driver.
++ *
++ *  @return      n/a
++ */
++void __exit
++sbi_unregister(void)
++{
++    ENTER();
++
++    /* SDIO Driver Unregistration */
++    sdio_unregister_driver(&uap_sdio);
++
++    LEAVE();
++}
++
++/**
++ *  @brief This function checks the interrupt status and handle it accordingly.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param ireg    A pointer to variable that keeps returned value
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++sbi_get_int_status(uap_private * priv, u8 * ireg)
++{
++    int ret = UAP_STATUS_SUCCESS;
++    u8 sdio_ireg = 0;
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++
++    ENTER();
++
++    *ireg = 0;
++    OS_INT_DISABLE;
++    sdio_ireg = sd_ireg;
++    sd_ireg = 0;
++    OS_INT_RESTORE;
++
++    sdio_claim_host(card->func);
++
++    if (sdio_ireg & DN_LD_HOST_INT_STATUS) {    /* tx_done INT */
++        if (!priv->uap_dev.cmd_sent) {  /* tx_done already received */
++            PRINTM(INFO,
++                   "warning: tx_done already received: tx_dnld_rdy=0x%x int status=0x%x\n",
++                   priv->uap_dev.cmd_sent, sdio_ireg);
++        } else {
++            priv->uap_dev.cmd_sent = FALSE;
++            priv->uap_dev.data_sent = FALSE;
++            if ( (priv->uap_dev.netdev->reg_state == NETREG_REGISTERED) && (skb_queue_len(&priv->adapter->tx_queue) < TX_LOW_WATERMARK)) {
++                os_start_queue(priv);
++          }
++        }
++    }
++    if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
++        sd_card_to_host(priv);
++    }
++
++    *ireg = sdio_ireg;
++    ret = UAP_STATUS_SUCCESS;
++    sdio_release_host(card->func);
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function disables the host interrupts.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++sbi_disable_host_int(uap_private * priv)
++{
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++    int ret;
++
++    ENTER();
++
++    sdio_claim_host(card->func);
++    ret = disable_host_int_mask(priv, HIM_DISABLE);
++    sdio_release_host(card->func);
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function enables the host interrupts.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS
++ */
++int
++sbi_enable_host_int(uap_private * priv)
++{
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++    int ret;
++
++    ENTER();
++
++    sdio_claim_host(card->func);
++    ret = enable_host_int_mask(priv, HIM_ENABLE);
++    sdio_release_host(card->func);
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function de-registers the device.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS
++ */
++int
++sbi_unregister_dev(uap_private * priv)
++{
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++
++    ENTER();
++
++    if (!card || !card->func) {
++        PRINTM(ERROR, "Error: card or function is NULL!\n");
++        goto done;
++    }
++
++    sdio_claim_host(card->func);
++    sdio_release_irq(card->func);
++    sdio_disable_func(card->func);
++    sdio_release_host(card->func);
++
++    sdio_set_drvdata(card->func, NULL);
++
++  done:
++    LEAVE();
++    return UAP_STATUS_SUCCESS;
++}
++
++/**
++ *  @brief This function registers the device.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++sbi_register_dev(uap_private * priv)
++{
++    int ret = UAP_STATUS_FAILURE;
++    u8 reg;
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++    struct sdio_func *func;
++
++    ENTER();
++
++    if (!card || !card->func) {
++        PRINTM(ERROR, "Error: card or function is NULL!\n");
++        goto done;
++    }
++
++    func = card->func;
++
++    /* Initialize the private structure */
++    priv->uap_dev.ioport = 0;
++
++    sdio_claim_host(func);
++
++    ret = sdio_enable_func(func);
++    if (ret) {
++        PRINTM(FATAL, "sdio_enable_func() failed: ret=%d\n", ret);
++        goto release_host;
++    }
++
++    ret = sdio_claim_irq(func, sbi_interrupt);
++    if (ret) {
++        PRINTM(FATAL, "sdio_claim_irq failed: ret=%d\n", ret);
++        goto disable_func;
++    }
++
++    /* Read the IO port */
++    ret = sbi_read_ioreg(priv, IO_PORT_0_REG, &reg);
++    if (ret)
++        goto release_irq;
++    else
++        priv->uap_dev.ioport |= reg;
++
++    ret = sbi_read_ioreg(priv, IO_PORT_1_REG, &reg);
++    if (ret)
++        goto release_irq;
++    else
++        priv->uap_dev.ioport |= (reg << 8);
++
++    ret = sbi_read_ioreg(priv, IO_PORT_2_REG, &reg);
++    if (ret)
++        goto release_irq;
++    else
++        priv->uap_dev.ioport |= (reg << 16);
++
++    PRINTM(INFO, "SDIO FUNC #%d IO port: 0x%x\n", func->num,
++           priv->uap_dev.ioport);
++
++    ret = sdio_set_block_size(card->func, SD_BLOCK_SIZE);
++    if (ret) {
++        PRINTM(ERROR, "%s: cannot set SDIO block size\n", __FUNCTION__);
++        ret = UAP_STATUS_FAILURE;
++        goto release_irq;
++    }
++    priv->hotplug_device = &func->dev;
++
++    if (helper_name == NULL) {
++        helper_name = DEFAULT_HELPER_NAME;
++    }
++    if (fw_name == NULL) {
++        fw_name = DEFAULT_FW_NAME;
++    }
++    sdio_release_host(func);
++
++    sdio_set_drvdata(func, card);
++
++    ret = UAP_STATUS_SUCCESS;
++    goto done;
++
++  release_irq:
++    sdio_release_irq(func);
++  disable_func:
++    sdio_disable_func(func);
++  release_host:
++    sdio_release_host(func);
++
++  done:
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function sends data to the card.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param payload A pointer to the data/cmd buffer
++ *  @param nb    the length of data/cmd
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb)
++{
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++    int ret = UAP_STATUS_SUCCESS;
++    int buf_block_len;
++    int blksz;
++    int i = 0;
++    u8 *buf = NULL;
++#ifdef PXA3XX_DMA_ALIGN
++    void *tmpbuf = NULL;
++    int tmpbufsz;
++#endif
++
++    ENTER();
++
++    if (!card || !card->func) {
++        PRINTM(ERROR, "card or function is NULL!\n");
++        LEAVE();
++        return UAP_STATUS_FAILURE;
++    }
++    buf = payload;
++#ifdef PXA3XX_DMA_ALIGN
++    if ((u32) payload & (PXA3XX_DMA_ALIGNMENT - 1)) {
++        tmpbufsz = ALIGN_SZ(nb, PXA3XX_DMA_ALIGNMENT);
++        tmpbuf = kmalloc(tmpbufsz, GFP_KERNEL);
++        memset(tmpbuf, 0, tmpbufsz);
++        /* Ensure 8-byte aligned CMD buffer */
++        buf = (u8 *) ALIGN_ADDR(tmpbuf, PXA3XX_DMA_ALIGNMENT);
++        memcpy(buf, payload, nb);
++    }
++#endif
++    /* Allocate buffer and copy payload */
++    blksz = SD_BLOCK_SIZE;
++    buf_block_len = (nb + blksz - 1) / blksz;
++    sdio_claim_host(card->func);
++#define MAX_WRITE_IOMEM_RETRY 2
++    priv->uap_dev.cmd_sent = TRUE;
++    priv->uap_dev.data_sent = TRUE;
++    do {
++        /* Transfer data to card */
++        ret = sdio_writesb(card->func, priv->uap_dev.ioport, buf,
++                           buf_block_len * blksz);
++        if (ret < 0) {
++            i++;
++            PRINTM(ERROR, "host_to_card, write iomem (%d) failed: %d\n", i,
++                   ret);
++            ret = UAP_STATUS_FAILURE;
++            if (i > MAX_WRITE_IOMEM_RETRY)
++                goto exit;
++        } else {
++            HEXDUMP("SDIO Blk Wr", payload, nb);
++        }
++    } while (ret == UAP_STATUS_FAILURE);
++  exit:
++    sdio_release_host(card->func);
++#ifdef PXA3XX_DMA_ALIGN
++    if (tmpbuf)
++        kfree(tmpbuf);
++#endif
++    if (ret == UAP_STATUS_FAILURE) {
++        priv->uap_dev.cmd_sent = FALSE;
++        priv->uap_dev.data_sent = FALSE;
++    }
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function reads CIS information.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param cisinfo A pointer to CIS information output buffer
++ *  @param cislen  A pointer to length of CIS info output buffer
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++#if 0
++static int
++sbi_get_cis_info(uap_private * priv, void *cisinfo, int *cislen)
++{
++#define CIS_PTR (0x8000)
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++    unsigned int i, cis_ptr = CIS_PTR;
++    int ret = UAP_STATUS_FAILURE;
++
++    ENTER();
++
++    if (!card || !card->func) {
++        PRINTM(ERROR, "sbi_get_cis_info(): card or function is NULL!\n");
++        goto exit;
++    }
++#define MAX_SDIO_CIS_INFO_LEN (256)
++    if (!cisinfo || (*cislen < MAX_SDIO_CIS_INFO_LEN)) {
++        PRINTM(WARN, "ERROR! get_cis_info: insufficient buffer passed\n");
++        goto exit;
++    }
++
++    *cislen = MAX_SDIO_CIS_INFO_LEN;
++
++    sdio_claim_host(card->func);
++
++    PRINTM(INFO, "cis_ptr=%#x\n", cis_ptr);
++
++    /* Read the Tuple Data */
++    for (i = 0; i < *cislen; i++) {
++        ((unsigned char *) cisinfo)[i] =
++            sdio_readb(card->func, cis_ptr + i, &ret);
++        if (ret) {
++            PRINTM(WARN, "get_cis_info error: ret=%d\n", ret);
++            ret = UAP_STATUS_FAILURE;
++            goto done;
++        }
++        PRINTM(INFO, "cisinfo[%d]=%#x\n", i, ((unsigned char *) cisinfo)[i]);
++    }
++
++  done:
++    sdio_release_host(card->func);
++  exit:
++    LEAVE();
++    return ret;
++}
++#endif
++/**
++ *  @brief This function downloads helper image to the card.
++ *
++ *  @param priv       A pointer to uap_private structure
++ *  @return           UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++sbi_prog_helper(uap_private * priv)
++{
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++    u8 *helper = NULL;
++    int helperlen;
++    int ret = UAP_STATUS_SUCCESS;
++    void *tmphlprbuf = NULL;
++    int tmphlprbufsz;
++    u8 *hlprbuf;
++    int hlprblknow;
++    u32 tx_len;
++#ifdef FW_DOWNLOAD_SPEED
++    u32 tv1, tv2;
++#endif
++
++    ENTER();
++
++    if (!card || !card->func) {
++        PRINTM(ERROR, "sbi_prog_helper(): card or function is NULL!\n");
++        goto done;
++    }
++
++    if (priv->fw_helper) {
++        helper = (u8 *) priv->fw_helper->data;
++        helperlen = priv->fw_helper->size;
++    } else {
++        PRINTM(MSG, "No helper image found! Terminating download.\n");
++        LEAVE();
++        return UAP_STATUS_FAILURE;
++    }
++
++    PRINTM(INFO, "Downloading helper image (%d bytes), block size %d bytes\n",
++           helperlen, SD_BLOCK_SIZE);
++
++#ifdef FW_DOWNLOAD_SPEED
++    tv1 = get_utimeofday();
++#endif
++
++#ifdef PXA3XX_DMA_ALIGN
++    tmphlprbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT);
++#else /* !PXA3XX_DMA_ALIGN */
++    tmphlprbufsz = UAP_UPLD_SIZE;
++#endif /* !PXA3XX_DMA_ALIGN */
++    tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL);
++    if (!tmphlprbuf) {
++        PRINTM(ERROR,
++               "Unable to allocate buffer for helper. Terminating download\n");
++        ret = UAP_STATUS_FAILURE;
++        goto done;
++    }
++    memset(tmphlprbuf, 0, tmphlprbufsz);
++#ifdef PXA3XX_DMA_ALIGN
++    hlprbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, PXA3XX_DMA_ALIGNMENT);
++#else /* !PXA3XX_DMA_ALIGN */
++    hlprbuf = (u8 *) tmphlprbuf;
++#endif /* !PXA3XX_DMA_ALIGN */
++
++    sdio_claim_host(card->func);
++
++    /* Perform helper data transfer */
++    tx_len = (FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE) - INTF_HEADER_LEN;
++    hlprblknow = 0;
++    do {
++        /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */
++        ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY);
++        if (ret < 0) {
++            PRINTM(FATAL, "Helper download poll status timeout @ %d\n",
++                   hlprblknow);
++            goto done;
++        }
++
++        /* More data? */
++        if (hlprblknow >= helperlen)
++            break;
++
++        /* Set blocksize to transfer - checking for last block */
++        if (helperlen - hlprblknow < tx_len)
++            tx_len = helperlen - hlprblknow;
++
++        /* Set length to the 4-byte header */
++        *(u32 *) hlprbuf = uap_cpu_to_le32(tx_len);
++
++        /* Copy payload to buffer */
++        memcpy(&hlprbuf[INTF_HEADER_LEN], &helper[hlprblknow], tx_len);
++
++        PRINTM(INFO, ".");
++
++        /* Send data */
++        ret = sdio_writesb(card->func, priv->uap_dev.ioport,
++                           hlprbuf, FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE);
++
++        if (ret < 0) {
++            PRINTM(FATAL, "IO error during helper download @ %d\n", hlprblknow);
++            goto done;
++        }
++
++        hlprblknow += tx_len;
++    } while (TRUE);
++
++#ifdef FW_DOWNLOAD_SPEED
++    tv2 = get_utimeofday();
++    PRINTM(INFO, "helper: %ld.%03ld.%03ld ", tv1 / 1000000,
++           (tv1 % 1000000) / 1000, tv1 % 1000);
++    PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000, (tv2 % 1000000) / 1000,
++           tv2 % 1000);
++    tv2 -= tv1;
++    PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000, (tv2 % 1000000) / 1000,
++           tv2 % 1000);
++#endif
++
++    /* Write last EOF data */
++    PRINTM(INFO, "\nTransferring helper image EOF block\n");
++    memset(hlprbuf, 0x0, SD_BLOCK_SIZE);
++    ret = sdio_writesb(card->func, priv->uap_dev.ioport,
++                       hlprbuf, SD_BLOCK_SIZE);
++
++    if (ret < 0) {
++        PRINTM(FATAL, "IO error in writing helper image EOF block\n");
++        goto done;
++    }
++
++    ret = UAP_STATUS_SUCCESS;
++
++  done:
++    sdio_release_host(card->func);
++    if (tmphlprbuf)
++        kfree(tmphlprbuf);
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function downloads firmware image to the card.
++ *
++ *  @param priv       A pointer to uap_private structure
++ *  @return           UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++sbi_prog_fw_w_helper(uap_private * priv)
++{
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++    u8 *firmware = NULL;
++    int firmwarelen;
++    u8 base0;
++    u8 base1;
++    int ret = UAP_STATUS_SUCCESS;
++    int offset;
++    void *tmpfwbuf = NULL;
++    int tmpfwbufsz;
++    u8 *fwbuf;
++    u16 len;
++    int txlen = 0;
++    int tx_blocks = 0;
++    int i = 0;
++    int tries = 0;
++#ifdef FW_DOWNLOAD_SPEED
++    u32 tv1, tv2;
++#endif
++
++    ENTER();
++
++    if (!card || !card->func) {
++        PRINTM(ERROR, "sbi_prog_fw_w_helper(): card or function is NULL!\n");
++        goto done;
++    }
++
++    if (priv->firmware) {
++        firmware = (u8 *) priv->firmware->data;
++        firmwarelen = priv->firmware->size;
++    } else {
++        PRINTM(MSG, "No firmware image found! Terminating download.\n");
++        LEAVE();
++        return UAP_STATUS_FAILURE;
++    }
++
++    PRINTM(INFO, "Downloading FW image (%d bytes)\n", firmwarelen);
++
++#ifdef FW_DOWNLOAD_SPEED
++    tv1 = get_utimeofday();
++#endif
++
++#ifdef PXA3XX_DMA_ALIGN
++    tmpfwbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT);
++#else /* PXA3XX_DMA_ALIGN */
++    tmpfwbufsz = UAP_UPLD_SIZE;
++#endif /* PXA3XX_DMA_ALIGN */
++    tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL);
++    if (!tmpfwbuf) {
++        PRINTM(ERROR,
++               "Unable to allocate buffer for firmware. Terminating download.\n");
++        ret = UAP_STATUS_FAILURE;
++        goto done;
++    }
++    memset(tmpfwbuf, 0, tmpfwbufsz);
++#ifdef PXA3XX_DMA_ALIGN
++    /* Ensure 8-byte aligned firmware buffer */
++    fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, PXA3XX_DMA_ALIGNMENT);
++#else /* PXA3XX_DMA_ALIGN */
++    fwbuf = (u8 *) tmpfwbuf;
++#endif /* PXA3XX_DMA_ALIGN */
++
++    sdio_claim_host(card->func);
++
++    /* Perform firmware data transfer */
++    offset = 0;
++    do {
++        /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */
++        ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY);
++        if (ret < 0) {
++            PRINTM(FATAL, "FW download with helper poll status timeout @ %d\n",
++                   offset);
++            goto done;
++        }
++
++        /* More data? */
++        if (offset >= firmwarelen)
++            break;
++
++        for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
++            if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_0, &base0)) < 0) {
++                PRINTM(WARN, "Dev BASE0 register read failed:"
++                       " base0=0x%04X(%d). Terminating download.\n", base0,
++                       base0);
++                ret = UAP_STATUS_FAILURE;
++                goto done;
++            }
++            if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_1, &base1)) < 0) {
++                PRINTM(WARN, "Dev BASE1 register read failed:"
++                       " base1=0x%04X(%d). Terminating download.\n", base1,
++                       base1);
++                ret = UAP_STATUS_FAILURE;
++                goto done;
++            }
++            len = (((u16) base1) << 8) | base0;
++
++            /* For SD8688 wait until the length is not 0, 1 or 2 before
++               downloading the first FW block, since BOOT code writes the
++               register to indicate the helper/FW download winner, the value
++               could be 1 or 2 (Func1 or Func2). */
++            if ((len && offset) || (len > 2))
++                break;
++            udelay(10);
++        }
++
++        if (len == 0)
++            break;
++        else if (len > UAP_UPLD_SIZE) {
++            PRINTM(FATAL, "FW download failure @ %d, invalid length %d\n",
++                   offset, len);
++            ret = UAP_STATUS_FAILURE;
++            goto done;
++        }
++
++        txlen = len;
++
++        if (len & BIT(0)) {
++            i++;
++            if (i > MAX_WRITE_IOMEM_RETRY) {
++                PRINTM(FATAL,
++                       "FW download failure @ %d, over max retry count\n",
++                       offset);
++                ret = UAP_STATUS_FAILURE;
++                goto done;
++            }
++            PRINTM(ERROR, "FW CRC error indicated by the helper:"
++                   " len = 0x%04X, txlen = %d\n", len, txlen);
++            len &= ~BIT(0);
++            /* Setting this to 0 to resend from same offset */
++            txlen = 0;
++        } else {
++            i = 0;
++
++            /* Set blocksize to transfer - checking for last block */
++            if (firmwarelen - offset < txlen) {
++                txlen = firmwarelen - offset;
++            }
++            PRINTM(INFO, ".");
++
++            tx_blocks = (txlen + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE;
++
++            /* Copy payload to buffer */
++            memcpy(fwbuf, &firmware[offset], txlen);
++        }
++
++        /* Send data */
++        ret = sdio_writesb(card->func, priv->uap_dev.ioport,
++                           fwbuf, tx_blocks * SD_BLOCK_SIZE);
++
++        if (ret < 0) {
++            PRINTM(ERROR, "FW download, write iomem (%d) failed @ %d\n", i,
++                   offset);
++            if (sbi_write_ioreg(priv, CONFIGURATION_REG, 0x04) < 0) {
++                PRINTM(ERROR, "write ioreg failed (CFG)\n");
++            }
++        }
++
++        offset += txlen;
++    } while (TRUE);
++
++    PRINTM(INFO, "\nFW download over, size %d bytes\n", offset);
++
++    ret = UAP_STATUS_SUCCESS;
++  done:
++#ifdef FW_DOWNLOAD_SPEED
++    tv2 = get_utimeofday();
++    PRINTM(INFO, "FW: %ld.%03ld.%03ld ", tv1 / 1000000,
++           (tv1 % 1000000) / 1000, tv1 % 1000);
++    PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000,
++           (tv2 % 1000000) / 1000, tv2 % 1000);
++    tv2 -= tv1;
++    PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000,
++           (tv2 % 1000000) / 1000, tv2 % 1000);
++#endif
++    sdio_release_host(card->func);
++    if (tmpfwbuf)
++        kfree(tmpfwbuf);
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function checks if the firmware is ready to accept
++ *  command or not.
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param pollnum Poll number
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++sbi_check_fw_status(uap_private * priv, int pollnum)
++{
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++    int ret = UAP_STATUS_SUCCESS;
++    u16 firmwarestat;
++    int tries;
++
++    ENTER();
++
++    sdio_claim_host(card->func);
++
++    /* Wait for firmware initialization event */
++    for (tries = 0; tries < pollnum; tries++) {
++        if ((ret = sd_read_firmware_status(priv, &firmwarestat)) < 0)
++            continue;
++        if (firmwarestat == FIRMWARE_READY) {
++            ret = UAP_STATUS_SUCCESS;
++            break;
++        } else {
++            mdelay(10);
++            ret = UAP_STATUS_FAILURE;
++        }
++    }
++
++    if (ret < 0)
++        goto done;
++
++    ret = UAP_STATUS_SUCCESS;
++    sd_get_rx_unit(priv);
++
++  done:
++    sdio_release_host(card->func);
++
++    LEAVE();
++    return ret;
++}
++
++/**
++ *  @brief This function set bus clock on/off
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @param option    TRUE--on , FALSE--off
++ *  @return      UAP_STATUS_SUCCESS
++ */
++#if 0
++static int
++sbi_set_bus_clock(uap_private * priv, u8 option)
++{
++    ENTER();
++    LEAVE();
++    return UAP_STATUS_SUCCESS;
++}
++#endif
++
++/**
++ *  @brief This function wakeup firmware
++ *
++ *  @param priv    A pointer to uap_private structure
++ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
++ */
++int
++sbi_wakeup_firmware(uap_private * priv)
++{
++    struct sdio_mmc_card *card = priv->uap_dev.card;
++    int ret = UAP_STATUS_SUCCESS;
++
++    ENTER();
++
++    if (!card || !card->func) {
++        PRINTM(ERROR, "card or function is NULL!\n");
++        LEAVE();
++        return UAP_STATUS_FAILURE;
++    }
++    sdio_claim_host(card->func);
++    sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
++    sdio_release_host(card->func);
++    LEAVE();
++    return ret;
++}
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h
+--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h    1970-01-01 01:00:00.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h        2014-12-29 20:37:43.955764567 +0100
+@@ -0,0 +1,136 @@
++/** @file uap_sdio_mmc.h
++ *  @brief This file contains SDIO IF (interface) module
++ *  related macros, enum, and structure.
++ *
++ * Copyright (C) 2007-2009, Marvell International Ltd.
++ *
++ * This software file (the "File") is distributed by Marvell International
++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
++ * (the "License").  You may use, redistribute and/or modify this File in
++ * accordance with the terms and conditions of the License, a copy of which
++ * is available along with the File in the gpl.txt file or by writing to
++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
++ *
++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
++ * this warranty disclaimer.
++ *
++ */
++/****************************************************
++Change log:
++      10/10/07: initial version
++****************************************************/
++
++#ifndef       _UAP_SDIO_MMC_H
++#define       _UAP_SDIO_MMC_H
++
++#include      <linux/mmc/sdio.h>
++#include      <linux/mmc/sdio_ids.h>
++#include      <linux/mmc/sdio_func.h>
++#include      <linux/mmc/card.h>
++
++#include      "uap_headers.h"
++
++/** The number of times to try when waiting for downloaded firmware to
++     become active. (polling the scratch register). */
++#define MAX_FIRMWARE_POLL_TRIES               100
++
++/** Firmware ready */
++#define FIRMWARE_READY                        0xfedc
++
++/** Number of firmware blocks to transfer */
++#define FIRMWARE_TRANSFER_NBLOCK      2
++
++/* Host Control Registers */
++/** Host Control Registers : I/O port 0 */
++#define IO_PORT_0_REG                 0x00
++/** Host Control Registers : I/O port 1 */
++#define IO_PORT_1_REG                 0x01
++/** Host Control Registers : I/O port 2 */
++#define IO_PORT_2_REG                 0x02
++
++/** Host Control Registers : Configuration */
++#define CONFIGURATION_REG             0x03
++/** Host Control Registers : Host without Command 53 finish host */
++#define HOST_WO_CMD53_FINISH_HOST     (0x1U << 2)
++/** Host Control Registers : Host power up */
++#define HOST_POWER_UP                 (0x1U << 1)
++/** Host Control Registers : Host power down */
++#define HOST_POWER_DOWN                       (0x1U << 0)
++
++/** Host Control Registers : Host interrupt mask */
++#define HOST_INT_MASK_REG             0x04
++/** Host Control Registers : Upload host interrupt mask */
++#define UP_LD_HOST_INT_MASK           (0x1U)
++/** Host Control Registers : Download host interrupt mask */
++#define DN_LD_HOST_INT_MASK           (0x2U)
++/** Enable Host interrupt mask */
++#define HIM_ENABLE                    (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
++/** Disable Host interrupt mask */
++#define       HIM_DISABLE                     0xff
++
++/** Host Control Registers : Host interrupt status */
++#define HOST_INTSTATUS_REG            0x05
++/** Host Control Registers : Upload host interrupt status */
++#define UP_LD_HOST_INT_STATUS         (0x1U)
++/** Host Control Registers : Download host interrupt status */
++#define DN_LD_HOST_INT_STATUS         (0x2U)
++
++/** Host F1 read base 0 */
++#define HOST_F1_RD_BASE_0             0x10
++/** Host F1 read base 1 */
++#define HOST_F1_RD_BASE_1             0x11
++
++/** Card Control Registers : Card status register */
++#define CARD_STATUS_REG               0x20
++/** Card Control Registers : Card I/O ready */
++#define CARD_IO_READY                 (0x1U << 3)
++/** Card Control Registers : CIS card ready */
++#define CIS_CARD_RDY                  (0x1U << 2)
++/** Card Control Registers : Upload card ready */
++#define UP_LD_CARD_RDY                (0x1U << 1)
++/** Card Control Registers : Download card ready */
++#define DN_LD_CARD_RDY                (0x1U << 0)
++
++/** Card Control Registers : Card OCR 0 register */
++#define CARD_OCR_0_REG                0x34
++/** Card Control Registers : Card OCR 1 register */
++#define CARD_OCR_1_REG                0x35
++
++/** Firmware status 0 register */
++#define CARD_FW_STATUS0_REG           0x40
++/** Firmware status 1 register */
++#define CARD_FW_STATUS1_REG           0x41
++/** Rx length register */
++#define CARD_RX_LEN_REG                       0x42
++/** Rx unit register */
++#define CARD_RX_UNIT_REG              0x43
++
++/** Chip Id Register 0 */
++#define CARD_CHIP_ID_0_REG            0x801c
++/** Chip Id Register 1 */
++#define CARD_CHIP_ID_1_REG            0x801d
++
++#ifdef PXA3XX_DMA_ALIGN
++/** DMA alignment value for PXA3XX platforms */
++#define PXA3XX_DMA_ALIGNMENT    8
++/** Macros for Data Alignment : size */
++#define ALIGN_SZ(p, a)  \
++    (((p) + ((a) - 1)) & ~((a) - 1))
++
++/** Macros for Data Alignment : address */
++#define ALIGN_ADDR(p, a)    \
++    ((((u32)(p)) + (((u32)(a)) - 1)) & ~(((u32)(a)) - 1))
++#endif /* PXA3XX_DMA_ALIGN */
++
++struct sdio_mmc_card
++{
++        /** sdio_func structure pointer */
++    struct sdio_func *func;
++        /** uap_private structure pointer */
++    uap_private *priv;
++};
++
++#endif /* _UAP_SDIO_MMC_H */
+diff -Naur backports-3.18.1-1.org/drivers/net/wireless/Makefile backports-3.18.1-1/drivers/net/wireless/Makefile
+--- backports-3.18.1-1.org/drivers/net/wireless/Makefile       2014-12-21 22:37:15.000000000 +0100
++++ backports-3.18.1-1/drivers/net/wireless/Makefile   2014-12-29 20:40:33.632440784 +0100
+@@ -60,3 +60,5 @@
+ obj-$(CPTCFG_CW1200)  += cw1200/
+ obj-$(CPTCFG_RSI_91X) += rsi/
++
++obj-$(CPTCFG_LIBERTAS_UAP)    += libertas_uap/