From fafaa38ae55cab486f2b929a131fe433ce180224 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 7 Oct 2012 12:50:15 +0000
Subject: [PATCH] move a few unmaintained packages from trunk to /packages

SVN-Revision: 33634
---
 package/bridge-utils/Makefile                 |   51 -
 .../patches/001-libbridge_cflags.patch        |   11 -
 package/crda/Makefile                         |   74 -
 package/crda/files/hotplug.rule               |    6 -
 .../101-make_crypto_use_optional.patch        |   13 -
 package/goldfish-qemu/Makefile                |   70 -
 .../patches/100-darwin_fix.patch              |   30 -
 .../patches/110-single_image.patch            |  233 --
 .../goldfish-qemu/skins/HVGA/arrow_down.png   |  Bin 3438 -> 0 bytes
 .../goldfish-qemu/skins/HVGA/arrow_left.png   |  Bin 4122 -> 0 bytes
 .../goldfish-qemu/skins/HVGA/arrow_right.png  |  Bin 4147 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/arrow_up.png |  Bin 3493 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/back.png     |  Bin 3564 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/device.png   |  Bin 45511 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/end.png      |  Bin 3562 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/home.png     |  Bin 3578 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/key.png      |  Bin 2857 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/keyboard.png |  Bin 11032 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/layout       |  380 ---
 package/goldfish-qemu/skins/HVGA/menu.png     |  Bin 3079 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/power.png    |  Bin 3782 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/select.png   |  Bin 3374 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/send.png     |  Bin 3561 -> 0 bytes
 package/goldfish-qemu/skins/HVGA/spacebar.png |  Bin 2916 -> 0 bytes
 .../goldfish-qemu/skins/HVGA/volume_down.png  |  Bin 3586 -> 0 bytes
 .../goldfish-qemu/skins/HVGA/volume_up.png    |  Bin 3856 -> 0 bytes
 package/libipfix/Makefile                     |   47 -
 package/libipfix/extra/append-wprobe-ie.pl    |   38 -
 package/libipfix/extra/wprobe-ie.txt          |   14 -
 .../libipfix/patches/100-openimp_sync.patch   |  474 ----
 package/libipfix/patches/110-wprobe_ie.patch  |   44 -
 package/libipfix/patches/120-ipfixmisc.patch  |   27 -
 package/madwifi/Config.in                     |   55 -
 package/madwifi/Makefile                      |  266 --
 .../files/etc/hotplug.d/net/10-madwifi        |   12 -
 package/madwifi/files/lib/wifi/madwifi.sh     |  498 ----
 .../files/lib/wifi/madwifi_countrycodes.txt   |  239 --
 .../patches/102-multicall_binary.patch        |  315 ---
 .../madwifi/patches/104-autocreate_none.patch |   11 -
 .../madwifi/patches/105-ratectl_attach.patch  |   23 -
 package/madwifi/patches/106-get_arch.patch    |   21 -
 .../madwifi/patches/111-minstrel_crash.patch  |   12 -
 .../madwifi/patches/113-no_ibss_pwrsave.patch |   12 -
 .../patches/122-replayfail_workaround.patch   |   12 -
 package/madwifi/patches/123-ccmp_checks.patch |   95 -
 .../madwifi/patches/124-linux24_compat.patch  |  202 --
 .../madwifi/patches/126-rxerr_frames.patch    |   13 -
 package/madwifi/patches/200-no_debug.patch    |  408 ---
 package/madwifi/patches/201-debug_fix.patch   |   20 -
 .../madwifi/patches/202-debug_variables.patch |  204 --
 .../madwifi/patches/300-napi_polling.patch    |  536 ----
 package/madwifi/patches/305-pureg_fix.patch   |  168 --
 .../madwifi/patches/309-micfail_detect.patch  |  321 ---
 package/madwifi/patches/310-noise_get.patch   |   55 -
 package/madwifi/patches/311-bssid_alloc.patch |   11 -
 package/madwifi/patches/312-erpupdate.patch   |   68 -
 package/madwifi/patches/317-bmask.patch       |   13 -
 .../madwifi/patches/323-dfs_optional.patch    |   38 -
 package/madwifi/patches/324-alignment.patch   |   19 -
 .../madwifi/patches/325-channel_spam.patch    |   28 -
 package/madwifi/patches/327-queue.patch       |   40 -
 package/madwifi/patches/330-beaconcal.patch   |  166 --
 .../madwifi/patches/331-memory_alloc.patch    |   36 -
 .../madwifi/patches/332-reset_beacons.patch   |   11 -
 package/madwifi/patches/333-apscan_mode.patch |   15 -
 package/madwifi/patches/334-input.patch       |   12 -
 package/madwifi/patches/340-maxrate.patch     |   98 -
 package/madwifi/patches/341-minrate.patch     |  114 -
 package/madwifi/patches/342-performance.patch |  263 --
 .../madwifi/patches/343-txqueue_races.patch   |   34 -
 .../patches/344-minstrel_failcnt.patch        |   11 -
 .../patches/345-minstrel_sampling.patch       |   80 -
 .../madwifi/patches/346-protmode_trig.patch   |  135 -
 package/madwifi/patches/347-tuning.patch      |   99 -
 package/madwifi/patches/348-ackcts.patch      |   38 -
 package/madwifi/patches/349-reset.patch       |   12 -
 .../madwifi/patches/350-wisoc_softled.patch   |   11 -
 package/madwifi/patches/351-scanlist.patch    |  904 -------
 package/madwifi/patches/352-ani_fix.patch     |  265 --
 package/madwifi/patches/353-devid.patch       |   19 -
 .../madwifi/patches/354-lantiq_eeprom.patch   |   95 -
 .../patches/355-eap_auth_disassoc.patch       |   77 -
 package/madwifi/patches/356-hidden_ssid.patch |   49 -
 .../madwifi/patches/357-bgscan_thresh.patch   |  160 --
 .../patches/358-ignore_broken_bssid.patch     |   18 -
 .../madwifi/patches/359-disable_reassoc.patch |   31 -
 package/madwifi/patches/360-sta_nodes.patch   |  242 --
 .../madwifi/patches/361-bmiss_handling.patch  |  102 -
 package/madwifi/patches/362-rssithr.patch     |   93 -
 package/madwifi/patches/363-fix_turbo.patch   |   11 -
 .../madwifi/patches/364-memory_alloc.patch    |   13 -
 .../patches/365-turbo_channelsearch.patch     |   10 -
 .../madwifi/patches/366-bstuck_thresh.patch   |   52 -
 package/madwifi/patches/367-roaming.patch     |   77 -
 .../madwifi/patches/368-sta_ie_preserve.patch |   49 -
 package/madwifi/patches/369-mlme_assoc.patch  |   10 -
 package/madwifi/patches/370-wdsvap.patch      | 1665 ------------
 package/madwifi/patches/372-queue_vif.patch   |   39 -
 .../madwifi/patches/373-sanity_check.patch    |   12 -
 package/madwifi/patches/374-nbtt_fix.patch    |   22 -
 .../madwifi/patches/375-atim_tsf_update.patch |  141 -
 .../patches/377-disable_vlan_code.patch       |   25 -
 .../madwifi/patches/378-adhoc_crash_fix.patch |   14 -
 .../patches/379-invalid_rate_fix.patch        |  405 ---
 .../madwifi/patches/380-noderef_hack.patch    |   13 -
 package/madwifi/patches/381-ibss_modes.patch  |   23 -
 .../madwifi/patches/382-relax_bintval.patch   |   13 -
 package/madwifi/patches/383-ibss_hostap.patch |  105 -
 package/madwifi/patches/384-hwdetect.patch    |  325 ---
 package/madwifi/patches/385-antenna_fix.patch |   10 -
 .../madwifi/patches/386-acl_crashfix.patch    |  116 -
 package/madwifi/patches/387-maxassoc.patch    |   85 -
 package/madwifi/patches/388-apsta_fix.patch   |   60 -
 package/madwifi/patches/389-autochannel.patch |  249 --
 package/madwifi/patches/390-frame_type.patch  |   13 -
 package/madwifi/patches/391-vap_auth.patch    |   29 -
 .../patches/392-remove_wds_nodetracking.patch |  388 ---
 .../madwifi/patches/393-mbss_vap_auth.patch   |  491 ----
 package/madwifi/patches/394-probereq.patch    |   64 -
 .../madwifi/patches/395-ath_ff_unmap.patch    |   11 -
 package/madwifi/patches/396-napi_ff_fix.patch |   65 -
 package/madwifi/patches/400-new_hal.patch     |  153 --
 .../madwifi/patches/401-changeset_r3602.patch |   11 -
 .../madwifi/patches/402-changeset_r3603.patch |  176 --
 .../madwifi/patches/403-changeset_r3605.patch |   70 -
 package/madwifi/patches/404-linux24_fix.patch |   15 -
 .../patches/405-retransmit_check.patch        |   22 -
 .../madwifi/patches/406-monitor_r3711.patch   |   20 -
 package/madwifi/patches/407-new_athinfo.patch | 2352 -----------------
 .../madwifi/patches/408-changeset_r3337.patch |   34 -
 package/madwifi/patches/409-wext_compat.patch |  133 -
 .../madwifi/patches/410-ar231x_2.6.28.patch   |  281 --
 .../patches/411-autochannel_multi.patch       |  347 ---
 .../patches/412-fragmentation_fix.patch       |   10 -
 package/madwifi/patches/413-rxorn.patch       |   31 -
 package/madwifi/patches/414-txpower.patch     |  262 --
 package/madwifi/patches/415-chan_switch.patch |  187 --
 package/madwifi/patches/416-wprobe.patch      |  549 ----
 .../madwifi/patches/417-beacon_txpower.patch  |   81 -
 .../madwifi/patches/419-skb_unmap_crash.patch |   20 -
 .../madwifi/patches/420-diversity_fix.patch   |   86 -
 .../patches/421-channel_handling.patch        | 1351 ----------
 .../patches/422-confchange_reset.patch        |   31 -
 .../madwifi/patches/423-phyerr_handling.patch |   28 -
 package/madwifi/patches/424-timing.patch      |  764 ------
 package/madwifi/patches/425-rc_rexmit.patch   |  506 ----
 package/madwifi/patches/426-header_len.patch  |   12 -
 .../patches/427-ignore_eeprom_ff.patch        |   11 -
 .../madwifi/patches/430-use_netdev_priv.patch | 1936 --------------
 .../madwifi/patches/431-compile_fixes.patch   |   35 -
 package/madwifi/patches/432-netdev_ops.patch  |  184 --
 .../433-backport_remove_irq_none.patch        |   21 -
 .../madwifi/patches/434-name-alloc-fix.patch  |   28 -
 .../patches/435-ibss_neighbor_fix.patch       |   11 -
 .../patches/436-injection_checks.patch        |   26 -
 .../madwifi/patches/437-sysctl_cleanup.patch  |   73 -
 .../patches/438-poweroffset_sysctl.patch      |   59 -
 .../patches/439-wlanconfig_stack_usage.patch  |   20 -
 package/madwifi/patches/440-wme_cleanup.patch |  136 -
 .../patches/441-fix_ibss_node_handling.patch  |   91 -
 .../madwifi/patches/442-ibss_rx_filter.patch  |   20 -
 .../madwifi/patches/443-tx_drop_counter.patch |   25 -
 .../patches/444-beacon_update_war.patch       |   17 -
 .../patches/445-fix_ps_sta_count.patch        |   18 -
 .../madwifi/patches/446-single_module.patch   |  778 ------
 .../madwifi/patches/447-sta_reconnect.patch   |   25 -
 .../patches/448-beacon_handling_fixes.patch   |  407 ---
 .../madwifi/patches/449-fix_txbuf_leak.patch  |   10 -
 package/madwifi/patches/450-calibration.patch |  177 --
 .../madwifi/patches/451-ibss_race_fix.patch   |  342 ---
 .../patches/452-minstrel_no_timer.patch       |  134 -
 package/madwifi/patches/453-procps.patch      |   55 -
 package/madwifi/patches/454-cca.patch         |  186 --
 .../madwifi/patches/455-beacon_watchdog.patch |   95 -
 package/madwifi/patches/456-rfsilent.patch    |   85 -
 package/madwifi/patches/457-idletime.patch    |  151 --
 .../madwifi/patches/458-ibss_wpa_none.patch   |   13 -
 .../madwifi/patches/459-2.6.33_compile.patch  |  524 ----
 .../patches/460-pci_softled_disable.patch     |   18 -
 .../patches/461-rx_stats_count_fix.patch      |   23 -
 package/madwifi/patches/462-fix_ap_scan.patch |   26 -
 .../patches/463-fix_txrate_display.patch      |   10 -
 .../patches/464-0dbm_txpower_fix.patch        |   30 -
 .../madwifi/patches/465-mc_list-2.6.35.patch  |   40 -
 .../madwifi/patches/466-2.6.38_compile.patch  |   14 -
 ...ac_addresss_from_ath5k_platform_data.patch |   36 -
 .../patches/471-netdev_ops_mac_mtu.patch      |   30 -
 .../patches/472-remove_11n_devids.patch       |   20 -
 package/madwifi/patches/473-mutex_fix.patch   |   11 -
 .../patches/474_fix_ssid_scan_length.patch    |   29 -
 .../madwifi/patches/475-2.6.39-compile.patch  |   11 -
 .../patches/476-3.0_detection_fix.patch       |   25 -
 package/madwifi/patches/477-3.2_fixes.patch   |   45 -
 .../patches/478-remove_vlan_code.patch        |   21 -
 package/ps3-utils/Makefile                    |   70 -
 package/redboot-ar231x/Makefile               |   52 -
 .../patches/010-fix-compile.patch             |  181 --
 package/siit/Makefile                         |   40 -
 package/siit/src/Makefile                     |    5 -
 package/siit/src/siit.c                       | 1478 -----------
 package/siit/src/siit.h                       |   61 -
 package/wprobe/Makefile                       |  143 -
 package/wprobe/files/wprobe.config            |   10 -
 package/wprobe/files/wprobe.init              |   72 -
 package/wprobe/src/Makefile.inc               |   12 -
 package/wprobe/src/exporter/Makefile          |    5 -
 package/wprobe/src/exporter/wprobe-export.c   |  304 ---
 package/wprobe/src/exporter/wprobe-export.h   |   34 -
 package/wprobe/src/filter/README.txt          |    1 -
 package/wprobe/src/filter/gen_filter.pl       |   63 -
 package/wprobe/src/filter/pfc.c               |   58 -
 package/wprobe/src/kernel/Makefile            |    5 -
 package/wprobe/src/kernel/linux/wprobe.h      |  397 ---
 package/wprobe/src/kernel/wprobe-core.c       | 1164 --------
 package/wprobe/src/kernel/wprobe-dummy.c      |   96 -
 package/wprobe/src/user/Makefile              |   38 -
 package/wprobe/src/user/list.h                |  601 -----
 package/wprobe/src/user/wprobe-lib.c          | 1210 ---------
 package/wprobe/src/user/wprobe-util.c         |  450 ----
 package/wprobe/src/user/wprobe.h              |  213 --
 220 files changed, 33399 deletions(-)
 delete mode 100644 package/bridge-utils/Makefile
 delete mode 100644 package/bridge-utils/patches/001-libbridge_cflags.patch
 delete mode 100644 package/crda/Makefile
 delete mode 100644 package/crda/files/hotplug.rule
 delete mode 100644 package/crda/patches/101-make_crypto_use_optional.patch
 delete mode 100644 package/goldfish-qemu/Makefile
 delete mode 100644 package/goldfish-qemu/patches/100-darwin_fix.patch
 delete mode 100644 package/goldfish-qemu/patches/110-single_image.patch
 delete mode 100644 package/goldfish-qemu/skins/HVGA/arrow_down.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/arrow_left.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/arrow_right.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/arrow_up.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/back.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/device.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/end.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/home.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/key.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/keyboard.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/layout
 delete mode 100644 package/goldfish-qemu/skins/HVGA/menu.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/power.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/select.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/send.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/spacebar.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/volume_down.png
 delete mode 100644 package/goldfish-qemu/skins/HVGA/volume_up.png
 delete mode 100644 package/libipfix/Makefile
 delete mode 100644 package/libipfix/extra/append-wprobe-ie.pl
 delete mode 100644 package/libipfix/extra/wprobe-ie.txt
 delete mode 100644 package/libipfix/patches/100-openimp_sync.patch
 delete mode 100644 package/libipfix/patches/110-wprobe_ie.patch
 delete mode 100644 package/libipfix/patches/120-ipfixmisc.patch
 delete mode 100644 package/madwifi/Config.in
 delete mode 100644 package/madwifi/Makefile
 delete mode 100644 package/madwifi/files/etc/hotplug.d/net/10-madwifi
 delete mode 100755 package/madwifi/files/lib/wifi/madwifi.sh
 delete mode 100644 package/madwifi/files/lib/wifi/madwifi_countrycodes.txt
 delete mode 100644 package/madwifi/patches/102-multicall_binary.patch
 delete mode 100644 package/madwifi/patches/104-autocreate_none.patch
 delete mode 100644 package/madwifi/patches/105-ratectl_attach.patch
 delete mode 100644 package/madwifi/patches/106-get_arch.patch
 delete mode 100644 package/madwifi/patches/111-minstrel_crash.patch
 delete mode 100644 package/madwifi/patches/113-no_ibss_pwrsave.patch
 delete mode 100644 package/madwifi/patches/122-replayfail_workaround.patch
 delete mode 100644 package/madwifi/patches/123-ccmp_checks.patch
 delete mode 100644 package/madwifi/patches/124-linux24_compat.patch
 delete mode 100644 package/madwifi/patches/126-rxerr_frames.patch
 delete mode 100644 package/madwifi/patches/200-no_debug.patch
 delete mode 100644 package/madwifi/patches/201-debug_fix.patch
 delete mode 100644 package/madwifi/patches/202-debug_variables.patch
 delete mode 100644 package/madwifi/patches/300-napi_polling.patch
 delete mode 100644 package/madwifi/patches/305-pureg_fix.patch
 delete mode 100644 package/madwifi/patches/309-micfail_detect.patch
 delete mode 100644 package/madwifi/patches/310-noise_get.patch
 delete mode 100644 package/madwifi/patches/311-bssid_alloc.patch
 delete mode 100644 package/madwifi/patches/312-erpupdate.patch
 delete mode 100644 package/madwifi/patches/317-bmask.patch
 delete mode 100644 package/madwifi/patches/323-dfs_optional.patch
 delete mode 100644 package/madwifi/patches/324-alignment.patch
 delete mode 100644 package/madwifi/patches/325-channel_spam.patch
 delete mode 100644 package/madwifi/patches/327-queue.patch
 delete mode 100644 package/madwifi/patches/330-beaconcal.patch
 delete mode 100644 package/madwifi/patches/331-memory_alloc.patch
 delete mode 100644 package/madwifi/patches/332-reset_beacons.patch
 delete mode 100644 package/madwifi/patches/333-apscan_mode.patch
 delete mode 100644 package/madwifi/patches/334-input.patch
 delete mode 100644 package/madwifi/patches/340-maxrate.patch
 delete mode 100644 package/madwifi/patches/341-minrate.patch
 delete mode 100644 package/madwifi/patches/342-performance.patch
 delete mode 100644 package/madwifi/patches/343-txqueue_races.patch
 delete mode 100644 package/madwifi/patches/344-minstrel_failcnt.patch
 delete mode 100644 package/madwifi/patches/345-minstrel_sampling.patch
 delete mode 100644 package/madwifi/patches/346-protmode_trig.patch
 delete mode 100644 package/madwifi/patches/347-tuning.patch
 delete mode 100644 package/madwifi/patches/348-ackcts.patch
 delete mode 100644 package/madwifi/patches/349-reset.patch
 delete mode 100644 package/madwifi/patches/350-wisoc_softled.patch
 delete mode 100644 package/madwifi/patches/351-scanlist.patch
 delete mode 100644 package/madwifi/patches/352-ani_fix.patch
 delete mode 100644 package/madwifi/patches/353-devid.patch
 delete mode 100644 package/madwifi/patches/354-lantiq_eeprom.patch
 delete mode 100644 package/madwifi/patches/355-eap_auth_disassoc.patch
 delete mode 100644 package/madwifi/patches/356-hidden_ssid.patch
 delete mode 100644 package/madwifi/patches/357-bgscan_thresh.patch
 delete mode 100644 package/madwifi/patches/358-ignore_broken_bssid.patch
 delete mode 100644 package/madwifi/patches/359-disable_reassoc.patch
 delete mode 100644 package/madwifi/patches/360-sta_nodes.patch
 delete mode 100644 package/madwifi/patches/361-bmiss_handling.patch
 delete mode 100644 package/madwifi/patches/362-rssithr.patch
 delete mode 100644 package/madwifi/patches/363-fix_turbo.patch
 delete mode 100644 package/madwifi/patches/364-memory_alloc.patch
 delete mode 100644 package/madwifi/patches/365-turbo_channelsearch.patch
 delete mode 100644 package/madwifi/patches/366-bstuck_thresh.patch
 delete mode 100644 package/madwifi/patches/367-roaming.patch
 delete mode 100644 package/madwifi/patches/368-sta_ie_preserve.patch
 delete mode 100644 package/madwifi/patches/369-mlme_assoc.patch
 delete mode 100644 package/madwifi/patches/370-wdsvap.patch
 delete mode 100644 package/madwifi/patches/372-queue_vif.patch
 delete mode 100644 package/madwifi/patches/373-sanity_check.patch
 delete mode 100644 package/madwifi/patches/374-nbtt_fix.patch
 delete mode 100644 package/madwifi/patches/375-atim_tsf_update.patch
 delete mode 100644 package/madwifi/patches/377-disable_vlan_code.patch
 delete mode 100644 package/madwifi/patches/378-adhoc_crash_fix.patch
 delete mode 100644 package/madwifi/patches/379-invalid_rate_fix.patch
 delete mode 100644 package/madwifi/patches/380-noderef_hack.patch
 delete mode 100644 package/madwifi/patches/381-ibss_modes.patch
 delete mode 100644 package/madwifi/patches/382-relax_bintval.patch
 delete mode 100644 package/madwifi/patches/383-ibss_hostap.patch
 delete mode 100644 package/madwifi/patches/384-hwdetect.patch
 delete mode 100644 package/madwifi/patches/385-antenna_fix.patch
 delete mode 100644 package/madwifi/patches/386-acl_crashfix.patch
 delete mode 100644 package/madwifi/patches/387-maxassoc.patch
 delete mode 100644 package/madwifi/patches/388-apsta_fix.patch
 delete mode 100644 package/madwifi/patches/389-autochannel.patch
 delete mode 100644 package/madwifi/patches/390-frame_type.patch
 delete mode 100644 package/madwifi/patches/391-vap_auth.patch
 delete mode 100644 package/madwifi/patches/392-remove_wds_nodetracking.patch
 delete mode 100644 package/madwifi/patches/393-mbss_vap_auth.patch
 delete mode 100644 package/madwifi/patches/394-probereq.patch
 delete mode 100644 package/madwifi/patches/395-ath_ff_unmap.patch
 delete mode 100644 package/madwifi/patches/396-napi_ff_fix.patch
 delete mode 100644 package/madwifi/patches/400-new_hal.patch
 delete mode 100644 package/madwifi/patches/401-changeset_r3602.patch
 delete mode 100644 package/madwifi/patches/402-changeset_r3603.patch
 delete mode 100644 package/madwifi/patches/403-changeset_r3605.patch
 delete mode 100644 package/madwifi/patches/404-linux24_fix.patch
 delete mode 100644 package/madwifi/patches/405-retransmit_check.patch
 delete mode 100644 package/madwifi/patches/406-monitor_r3711.patch
 delete mode 100644 package/madwifi/patches/407-new_athinfo.patch
 delete mode 100644 package/madwifi/patches/408-changeset_r3337.patch
 delete mode 100644 package/madwifi/patches/409-wext_compat.patch
 delete mode 100644 package/madwifi/patches/410-ar231x_2.6.28.patch
 delete mode 100644 package/madwifi/patches/411-autochannel_multi.patch
 delete mode 100644 package/madwifi/patches/412-fragmentation_fix.patch
 delete mode 100644 package/madwifi/patches/413-rxorn.patch
 delete mode 100644 package/madwifi/patches/414-txpower.patch
 delete mode 100644 package/madwifi/patches/415-chan_switch.patch
 delete mode 100644 package/madwifi/patches/416-wprobe.patch
 delete mode 100644 package/madwifi/patches/417-beacon_txpower.patch
 delete mode 100644 package/madwifi/patches/419-skb_unmap_crash.patch
 delete mode 100644 package/madwifi/patches/420-diversity_fix.patch
 delete mode 100644 package/madwifi/patches/421-channel_handling.patch
 delete mode 100644 package/madwifi/patches/422-confchange_reset.patch
 delete mode 100644 package/madwifi/patches/423-phyerr_handling.patch
 delete mode 100644 package/madwifi/patches/424-timing.patch
 delete mode 100644 package/madwifi/patches/425-rc_rexmit.patch
 delete mode 100644 package/madwifi/patches/426-header_len.patch
 delete mode 100644 package/madwifi/patches/427-ignore_eeprom_ff.patch
 delete mode 100644 package/madwifi/patches/430-use_netdev_priv.patch
 delete mode 100644 package/madwifi/patches/431-compile_fixes.patch
 delete mode 100644 package/madwifi/patches/432-netdev_ops.patch
 delete mode 100644 package/madwifi/patches/433-backport_remove_irq_none.patch
 delete mode 100644 package/madwifi/patches/434-name-alloc-fix.patch
 delete mode 100644 package/madwifi/patches/435-ibss_neighbor_fix.patch
 delete mode 100644 package/madwifi/patches/436-injection_checks.patch
 delete mode 100644 package/madwifi/patches/437-sysctl_cleanup.patch
 delete mode 100644 package/madwifi/patches/438-poweroffset_sysctl.patch
 delete mode 100644 package/madwifi/patches/439-wlanconfig_stack_usage.patch
 delete mode 100644 package/madwifi/patches/440-wme_cleanup.patch
 delete mode 100644 package/madwifi/patches/441-fix_ibss_node_handling.patch
 delete mode 100644 package/madwifi/patches/442-ibss_rx_filter.patch
 delete mode 100644 package/madwifi/patches/443-tx_drop_counter.patch
 delete mode 100644 package/madwifi/patches/444-beacon_update_war.patch
 delete mode 100644 package/madwifi/patches/445-fix_ps_sta_count.patch
 delete mode 100644 package/madwifi/patches/446-single_module.patch
 delete mode 100644 package/madwifi/patches/447-sta_reconnect.patch
 delete mode 100644 package/madwifi/patches/448-beacon_handling_fixes.patch
 delete mode 100644 package/madwifi/patches/449-fix_txbuf_leak.patch
 delete mode 100644 package/madwifi/patches/450-calibration.patch
 delete mode 100644 package/madwifi/patches/451-ibss_race_fix.patch
 delete mode 100644 package/madwifi/patches/452-minstrel_no_timer.patch
 delete mode 100644 package/madwifi/patches/453-procps.patch
 delete mode 100644 package/madwifi/patches/454-cca.patch
 delete mode 100644 package/madwifi/patches/455-beacon_watchdog.patch
 delete mode 100644 package/madwifi/patches/456-rfsilent.patch
 delete mode 100644 package/madwifi/patches/457-idletime.patch
 delete mode 100644 package/madwifi/patches/458-ibss_wpa_none.patch
 delete mode 100644 package/madwifi/patches/459-2.6.33_compile.patch
 delete mode 100644 package/madwifi/patches/460-pci_softled_disable.patch
 delete mode 100644 package/madwifi/patches/461-rx_stats_count_fix.patch
 delete mode 100644 package/madwifi/patches/462-fix_ap_scan.patch
 delete mode 100644 package/madwifi/patches/463-fix_txrate_display.patch
 delete mode 100644 package/madwifi/patches/464-0dbm_txpower_fix.patch
 delete mode 100644 package/madwifi/patches/465-mc_list-2.6.35.patch
 delete mode 100644 package/madwifi/patches/466-2.6.38_compile.patch
 delete mode 100644 package/madwifi/patches/470-mac_addresss_from_ath5k_platform_data.patch
 delete mode 100644 package/madwifi/patches/471-netdev_ops_mac_mtu.patch
 delete mode 100644 package/madwifi/patches/472-remove_11n_devids.patch
 delete mode 100644 package/madwifi/patches/473-mutex_fix.patch
 delete mode 100644 package/madwifi/patches/474_fix_ssid_scan_length.patch
 delete mode 100644 package/madwifi/patches/475-2.6.39-compile.patch
 delete mode 100644 package/madwifi/patches/476-3.0_detection_fix.patch
 delete mode 100644 package/madwifi/patches/477-3.2_fixes.patch
 delete mode 100644 package/madwifi/patches/478-remove_vlan_code.patch
 delete mode 100644 package/ps3-utils/Makefile
 delete mode 100644 package/redboot-ar231x/Makefile
 delete mode 100644 package/redboot-ar231x/patches/010-fix-compile.patch
 delete mode 100644 package/siit/Makefile
 delete mode 100644 package/siit/src/Makefile
 delete mode 100644 package/siit/src/siit.c
 delete mode 100644 package/siit/src/siit.h
 delete mode 100644 package/wprobe/Makefile
 delete mode 100644 package/wprobe/files/wprobe.config
 delete mode 100755 package/wprobe/files/wprobe.init
 delete mode 100644 package/wprobe/src/Makefile.inc
 delete mode 100644 package/wprobe/src/exporter/Makefile
 delete mode 100644 package/wprobe/src/exporter/wprobe-export.c
 delete mode 100644 package/wprobe/src/exporter/wprobe-export.h
 delete mode 100644 package/wprobe/src/filter/README.txt
 delete mode 100755 package/wprobe/src/filter/gen_filter.pl
 delete mode 100644 package/wprobe/src/filter/pfc.c
 delete mode 100644 package/wprobe/src/kernel/Makefile
 delete mode 100644 package/wprobe/src/kernel/linux/wprobe.h
 delete mode 100644 package/wprobe/src/kernel/wprobe-core.c
 delete mode 100644 package/wprobe/src/kernel/wprobe-dummy.c
 delete mode 100644 package/wprobe/src/user/Makefile
 delete mode 100644 package/wprobe/src/user/list.h
 delete mode 100644 package/wprobe/src/user/wprobe-lib.c
 delete mode 100644 package/wprobe/src/user/wprobe-util.c
 delete mode 100644 package/wprobe/src/user/wprobe.h

diff --git a/package/bridge-utils/Makefile b/package/bridge-utils/Makefile
deleted file mode 100644
index f87551c6c4..0000000000
--- a/package/bridge-utils/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-# 
-# Copyright (C) 2006-2012 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=bridge-utils
-PKG_RELEASE:=1
-PKG_SOURCE_URL:=@SF/bridge
-PKG_VERSION:=1.5
-PKG_MD5SUM:=ec7b381160b340648dede58c31bb2238
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/bridge
-  SECTION:=net
-  CATEGORY:=Base system
-  TITLE:=Ethernet bridging configuration utility
-  URL:=http://bridge.sourceforge.net/
-endef
-
-define Package/bridge/description
- Manage ethernet bridging: a way to connect networks together to 
- form a larger network.
-endef
-
-CONFIGURE_ARGS += \
-	--with-linux-headers="$(LINUX_DIR)" \
-
-define Build/Prepare
-$(call Build/Prepare/Default)
-	( cd $(PKG_BUILD_DIR) ; \
-		[ -f ./configure ] || { \
-			ln -sf configure.in configure.ac ; \
-			autoconf ; \
-		} \
-	)
-endef
-
-define Package/bridge/install
-	$(INSTALL_DIR) $(1)/usr/sbin
-	$(INSTALL_BIN) $(PKG_BUILD_DIR)/brctl/brctl $(1)/usr/sbin
-endef
-
-$(eval $(call BuildPackage,bridge))
diff --git a/package/bridge-utils/patches/001-libbridge_cflags.patch b/package/bridge-utils/patches/001-libbridge_cflags.patch
deleted file mode 100644
index e35a649474..0000000000
--- a/package/bridge-utils/patches/001-libbridge_cflags.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/libbridge/Makefile.in
-+++ b/libbridge/Makefile.in
-@@ -5,7 +5,7 @@ AR=ar
- RANLIB=@RANLIB@
- 
- CC=@CC@
--CFLAGS = -Wall -g $(KERNEL_HEADERS)
-+CFLAGS = -Wall -g @CFLAGS@ $(KERNEL_HEADERS)
- 
- prefix=@prefix@
- exec_prefix=@exec_prefix@
diff --git a/package/crda/Makefile b/package/crda/Makefile
deleted file mode 100644
index 0d075f1da5..0000000000
--- a/package/crda/Makefile
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# Copyright (C) 2009-2012 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=crda
-PKG_RELEASE:=1
-PKG_VERSION:=1.1.2
-PKG_SOURCE_URL:=http://wireless.kernel.org/download/crda
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_MD5SUM:=5226f65aebacf94baaf820f8b4e06df4
-
-PKG_REGULATORY_NAME:=regulatory
-PKG_REGULATORY_VERSION:=2011.04.28
-PKG_REGULATORY_SOURCE_URL:=http://wireless.kernel.org/download/wireless-regdb/regulatory.bins
-PKG_REGULATORY_SOURCE:=$(PKG_REGULATORY_VERSION)-$(PKG_REGULATORY_NAME).bin
-PKG_REGULATORY_MD5SUM:=1535e98bcaba732e2f8e8f62dac6f369
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/crda
-  SECTION:=net
-  CATEGORY:=Network
-  TITLE:=Central Regulatory Domain Agent (CRDA)
-  DEPENDS:=+libnl-tiny
-  URL:=http://wireless.kernel.org/en/developers/Regulatory/CRDA
-endef
-
-define Download/wireless-regdb
-  FILE:=$(PKG_REGULATORY_SOURCE)
-  URL:=$(PKG_REGULATORY_SOURCE_URL)
-  VERSION:=$(PKG_REGULATORY_VERSION)
-  MD5SUM:=$(PKG_REGULATORY_MD5SUM)
-endef
-$(eval $(call Download,wireless-regdb))
-
-define Package/crda/description
- This is the Central Regulatory Domain Agent for Linux. It serves one
- purpose: tell Linux kernel what to enforce. In essence it is a udev
- helper for communication between the kernel and userspace. You only
- need to run this manually for debugging purposes. For manual changing
- of regulatory domains use iw (iw reg set) or wpa_supplicant (feature
- yet to be added).
-endef
-
-TARGET_CPPFLAGS := \
-	-I$(STAGING_DIR)/usr/include/libnl-tiny \
-	-D_GNU_SOURCE \
-	$(TARGET_CPPFLAGS)
-
-MAKE_FLAGS += \
-	NL1FOUND="" NL2FOUND=Y \
-	NLLIBNAME="libnl-tiny" \
-	NLLIBS="-lnl-tiny -lm" \
-	REG_BIN="$(DL_DIR)/$(PKG_REGULATORY_SOURCE)" \
-	crda
-
-define Package/crda/install
-	$(INSTALL_DIR) $(1)/sbin
-	$(INSTALL_DIR) $(1)/etc/hotplug.d
-	$(INSTALL_DIR) $(1)/etc/hotplug.d/platform
-	$(INSTALL_DIR) $(1)/usr/lib/crda
-	$(INSTALL_BIN) $(PKG_BUILD_DIR)/crda $(1)/sbin/
-	$(INSTALL_DATA) ./files/hotplug.rule $(1)/etc/hotplug.d/platform/10-regulatory
-	$(INSTALL_DATA) $(DL_DIR)/$(PKG_REGULATORY_SOURCE) $(1)/usr/lib/crda/regulatory.bin
-endef
-
-$(eval $(call BuildPackage,crda))
-
diff --git a/package/crda/files/hotplug.rule b/package/crda/files/hotplug.rule
deleted file mode 100644
index 1ec033f46a..0000000000
--- a/package/crda/files/hotplug.rule
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2009 OpenWrt.org
-
-[ change = "$ACTION" -a regulatory.0 = "$DEVICENAME" ] && {
-	/sbin/crda
-}
diff --git a/package/crda/patches/101-make_crypto_use_optional.patch b/package/crda/patches/101-make_crypto_use_optional.patch
deleted file mode 100644
index c7ace42c84..0000000000
--- a/package/crda/patches/101-make_crypto_use_optional.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -35,7 +35,9 @@ LDLIBS += `pkg-config --libs openssl`
- 
- reglib.o: keys-ssl.c
- 
--else
-+endif
-+
-+ifeq ($(USE_GCRYPT),1)
- CFLAGS += -DUSE_GCRYPT
- LDLIBS += -lgcrypt
- 
diff --git a/package/goldfish-qemu/Makefile b/package/goldfish-qemu/Makefile
deleted file mode 100644
index e5b4083ea3..0000000000
--- a/package/goldfish-qemu/Makefile
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# Copyright (C) 2006-2010 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=goldfish-qemu
-PKG_REV:=2b8ea29e2bd12f876a4d06647e6077bf72de567e
-PKG_VERSION:=20090429
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=git://android.git.kernel.org/platform/external/qemu
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_VERSION:=$(PKG_REV)
-PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_TARGETS:=bin
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/goldfish-qemu
-  SECTION:=emulator
-  CATEGORY:=Emulators
-  DEPENDS:=@TARGET_goldfish
-  TITLE:=A modified version of the Google Android Emulator
-  URL:=http://www.android.com/
-endef
-
-LIBSDL_PATCHED:=sdl-1.2.12-android-20080919
-
-define Download/libsdl-patched
-  FILE:=$(LIBSDL_PATCHED).tar.gz
-  URL:=http://android.git.kernel.org/pub
-  MD5SUM:=22df8cbb2ecb811938eba8410e861650
-endef
-$(eval $(call Download,libsdl-patched))
-
-Build/Exports=
-
-define Build/Prepare
-	$(call Build/Prepare/Default)
-	zcat $(DL_DIR)/$(LIBSDL_PATCHED).tar.gz | tar x -C $(PKG_BUILD_DIR)
-endef
-
-define Build/Configure
-	[ -x $(PKG_BUILD_DIR)/libsdl/bin/sdl-config ] || ( \
-		cd $(PKG_BUILD_DIR)/$(LIBSDL_PATCHED); \
-		./android-configure --prefix=$(PKG_BUILD_DIR)/libsdl; \
-		make all install; \
-	)
-endef
-
-define Build/Compile
-	(cd $(PKG_BUILD_DIR); \
-		[ -f $(PKG_BUILD_DIR)/objs/config.make ] || \
-			./android-configure.sh --sdl-config=$(PKG_BUILD_DIR)/libsdl/bin/sdl-config \
-	)
-	$(MAKE) -C $(PKG_BUILD_DIR)
-endef
-
-define Package/goldfish-qemu/install
-	$(INSTALL_DIR) $(1)
-	$(CP) $(PKG_BUILD_DIR)/objs/emulator $(1)/
-	$(CP) ./skins $(1)/
-endef
-
-$(eval $(call BuildPackage,goldfish-qemu))
diff --git a/package/goldfish-qemu/patches/100-darwin_fix.patch b/package/goldfish-qemu/patches/100-darwin_fix.patch
deleted file mode 100644
index a5f56b3cf4..0000000000
--- a/package/goldfish-qemu/patches/100-darwin_fix.patch
+++ /dev/null
@@ -1,30 +0,0 @@
---- a/android-configure.sh
-+++ b/android-configure.sh
-@@ -656,6 +656,9 @@ case "$CPU" in
-     *) HOST_CPU=$CPU
-     ;;
- esac
-+case "$OS" in
-+    darwin*) echo "#define _BSD	1" >> $config_h;;
-+esac
- echo "#define HOST_$HOST_CPU    1" >> $config_h
- log "Generate   : $config_h"
- 
---- a/android/utils/display-quartz.m
-+++ b/android/utils/display-quartz.m
-@@ -34,6 +34,7 @@ get_monitor_resolution( int  *px_dpi, in
- int
- get_nearest_monitor_rect( int  *x, int  *y, int  *width, int  *height )
- {
-+#if 0
-     SDL_SysWMinfo  info;
-     NSWindow*      window;
- 
-@@ -108,4 +109,7 @@ get_nearest_monitor_rect( int  *x, int  
-         }
-         return 0;
-     }
-+#else
-+	return -1;
-+#endif
- };
diff --git a/package/goldfish-qemu/patches/110-single_image.patch b/package/goldfish-qemu/patches/110-single_image.patch
deleted file mode 100644
index 92a9e543dd..0000000000
--- a/package/goldfish-qemu/patches/110-single_image.patch
+++ /dev/null
@@ -1,233 +0,0 @@
---- a/android/cmdline-option.c
-+++ b/android/cmdline-option.c
-@@ -50,16 +50,6 @@ android_parse_options( int  *pargc, char
-         char   arg2_tab[64], *arg2 = arg2_tab;
-         int    nn;
- 
--        /* process @<name> as a special exception meaning
--         * '-avd <name>'
--         */
--        if (aread[0][0] == '@') {
--            opt->avd = aread[0]+1;
--            nargs--;
--            aread++;
--            continue;
--        }
--
-         /* anything that isn't an option past this points
-          * exits the loop
-          */
---- a/android/cmdline-options.h
-+++ b/android/cmdline-options.h
-@@ -60,21 +60,16 @@
-  */
- 
- CFG_PARAM( sysdir,  "<dir>",  "search for system disk images in <dir>" )
--CFG_PARAM( system,  "<file>", "read initial system image from <file>" )
--CFG_PARAM( datadir, "<dir>",  "write user data into <dir>" )
--CFG_PARAM( kernel,  "<file>", "use specific emulated kernel" )
--CFG_PARAM( ramdisk, "<file>", "ramdisk image (default <system>/ramdisk.img" )
--CFG_PARAM( image,   "<file>", "obsolete, use -system <file> instead" )
--CFG_PARAM( init_data, "<file>", "initial data image (default <system>/userdata.img" )
--CFG_PARAM( initdata, "<file>", "same as '-init-data <file>'" )
--CFG_PARAM( data,     "<file>", "data image (default <datadir>/userdata-qemu.img" )
-+CFG_PARAM( system,  "<file>", "read system image from <file>, default: <system>/system.img" )
-+CFG_PARAM( data,     "<file>", "data image, default: <system>/data.img" )
-+CFG_PARAM( kernel,  "<file>", "use specific emulated kernel, default: kernel.bin" )
-+CFG_PARAM( ramdisk, "<file>", "ramdisk image (default <system>/ramdisk.bin" )
- CFG_PARAM( partition_size, "<size>", "system/data partition size in MBs" )
- CFG_PARAM( cache,    "<file>", "cache partition image (default is temporary file)" )
- CFG_FLAG ( no_cache, "disable the cache partition" )
- CFG_FLAG ( nocache,  "same as -no-cache" )
- OPT_PARAM( sdcard, "<file>", "SD card image (default <system>/sdcard.img")
- OPT_FLAG ( wipe_data, "reset the use data image (copy it from initdata)" )
--CFG_PARAM( avd, "<name>", "use a specific android virtual device" )
- CFG_PARAM( skindir, "<dir>", "search skins in <dir> (default <system>/skins)" )
- CFG_PARAM( skin, "<name>", "select a given skin" )
- CFG_FLAG ( no_skin, "don't use any emulator skin" )
---- a/android/main.c
-+++ b/android/main.c
-@@ -1606,6 +1606,7 @@ report_console( const char*  proto_port,
-  *       containing 'fileName'. this is *not* the full
-  *       path to 'fileName'.
-  */
-+
- static char*
- _getSdkImagePath( const char*  fileName )
- {
-@@ -1617,8 +1618,6 @@ _getSdkImagePath( const char*  fileName 
- 
-     static const char* const  searchPaths[] = {
-         "",                                  /* program's directory */
--        "/lib/images",                       /* this is for SDK 1.0 */
--        "/../platforms/android-1.1/images",  /* this is for SDK 1.1 */
-         NULL
-     };
- 
-@@ -1841,25 +1840,7 @@ int main(int argc, char **argv)
-         }
-     }
- 
--    /* legacy support: we used to use -system <dir> and -image <file>
--     * instead of -sysdir <dir> and -system <file>, so handle this by checking
--     * whether the options point to directories or files.
--     */
--    if (opts->image != NULL) {
--        if (opts->system != NULL) {
--            if (opts->sysdir != NULL) {
--                derror( "You can't use -sysdir, -system and -image at the same time.\n"
--                        "You should probably use '-sysdir <path> -system <file>'.\n" );
--                exit(2);
--            }
--        }
--        dwarning( "Please note that -image is obsolete and that -system is now used to point\n"
--                  "to the system image. Next time, try using '-sysdir <path> -system <file>' instead.\n" );
--        opts->sysdir = opts->system;
--        opts->system = opts->image;
--        opts->image  = NULL;
--    }
--    else if (opts->system != NULL && path_is_dir(opts->system)) {
-+    if (opts->system != NULL && path_is_dir(opts->system)) {
-         if (opts->sysdir != NULL) {
-             derror( "Option -system should now be followed by a file path, not a directory one.\n"
-                     "Please use '-sysdir <path>' to point to the system directory.\n" );
-@@ -1885,49 +1866,11 @@ int main(int argc, char **argv)
-     if (opts->noskin)
-         opts->no_skin = opts->noskin;
- 
--    if (opts->initdata) {
--        opts->init_data = opts->initdata;
--        opts->initdata  = NULL;
--    }
--
--    /* If no AVD name was given, try to find the top of the
--     * Android build tree
--     */
--    if (opts->avd == NULL) {
--        do {
--            char*  out = getenv("ANDROID_PRODUCT_OUT");
--
--            if (out == NULL || out[0] == 0)
--                break;
--
--            if (!path_exists(out)) {
--                derror("Can't access ANDROID_PRODUCT_OUT as '%s'\n"
--                    "You need to build the Android system before launching the emulator",
--                    out);
--                exit(2);
--            }
--
--            android_build_root = path_parent( out, 4 );
--            if (android_build_root == NULL || !path_exists(android_build_root)) {
--                derror("Can't find the Android build root from '%s'\n"
--                    "Please check the definition of the ANDROID_PRODUCT_OUT variable.\n"
--                    "It should point to your product-specific build output directory.\n",
--                    out );
--                exit(2);
--            }
--            android_build_out = out;
--            D( "found Android build root: %s", android_build_root );
--            D( "found Android build out:  %s", android_build_out );
--        } while (0);
--    }
-     /* if no virtual device name is given, and we're not in the
-      * Android build system, we'll need to perform some auto-detection
-      * magic :-)
-      */
--    if (opts->avd == NULL && !android_build_out) 
-     {
--        char   dataDirIsSystem = 0;
--
-         if (!opts->sysdir) {
-             opts->sysdir = _getSdkImagePath("system.img");
-             if (!opts->sysdir) {
-@@ -1945,47 +1888,30 @@ int main(int argc, char **argv)
-         }
- 
-         if (!opts->system) {
--            opts->system = _getSdkSystemImage(opts->sysdir, "-image", "system.img");
--            D("autoconfig: -image %s", opts->image);
-+            opts->system = _getSdkSystemImage(opts->sysdir, "-system", "system.img");
-+            D("autoconfig: -system %s", opts->system);
-         }
- 
-         if (!opts->kernel) {
--            opts->kernel = _getSdkSystemImage(opts->sysdir, "-kernel", "kernel-qemu");
-+            opts->kernel = _getSdkSystemImage(opts->sysdir, "-kernel", "kernel.bin");
-             D("autoconfig: -kernel %s", opts->kernel);
-         }
- 
-         if (!opts->ramdisk) {
--            opts->ramdisk = _getSdkSystemImage(opts->sysdir, "-ramdisk", "ramdisk.img");
-+            opts->ramdisk = _getSdkSystemImage(opts->sysdir, "-ramdisk", "ramdisk.bin");
-             D("autoconfig: -ramdisk %s", opts->ramdisk);
-         }
- 
--        /* if no data directory is specified, use the system directory */
--        if (!opts->datadir) {
--            opts->datadir   = qemu_strdup(opts->sysdir);
--            dataDirIsSystem = 1;
--            D("autoconfig: -datadir %s", opts->sysdir);
--        }
--
-         if (!opts->data) {
-             /* check for userdata-qemu.img in the data directory */
--            bufprint(tmp, tmpend, "%s/userdata-qemu.img", opts->datadir);
--            if (!path_exists(tmp)) {
--                derror(
--                "You did not provide the name of an Android Virtual Device\n"
--                "with the '-avd <name>' option. Read -help-avd for more information.\n\n"
--
--                "If you *really* want to *NOT* run an AVD, consider using '-data <file>'\n"
--                "to specify a data partition image file (I hope you know what you're doing).\n"
--                );
--                exit(2);
--            }
-+            bufprint(tmp, tmpend, "%s/data.img", opts->sysdir);
- 
-             opts->data = qemu_strdup(tmp);
-             D("autoconfig: -data %s", opts->data);
-         }
- 
--        if (!opts->sdcard && opts->datadir) {
--            bufprint(tmp, tmpend, "%s/sdcard.img", opts->datadir);
-+        if (!opts->sdcard && opts->sysdir) {
-+            bufprint(tmp, tmpend, "%s/sdcard.img", opts->sysdir);
-             if (path_exists(tmp)) {
-                 opts->sdcard = qemu_strdup(tmp);
-                 D("autoconfig: -sdcard %s", opts->sdcard);
-@@ -2029,19 +1955,6 @@ int main(int argc, char **argv)
-     android_avdParams->skinName     = opts->skin;
-     android_avdParams->skinRootPath = opts->skindir;
- 
--    /* setup the virtual device differently depending on whether
--     * we are in the Android build system or not
--     */
--    if (opts->avd != NULL)
--    {
--        android_avdInfo = avdInfo_new( opts->avd, android_avdParams );
--        if (android_avdInfo == NULL) {
--            /* an error message has already been printed */
--            dprint("could not find virtual device named '%s'", opts->avd);
--            exit(1);
--        }
--    }
--    else
-     {
-         if (!android_build_out) {
-             android_build_out = android_build_root = opts->sysdir;
---- a/android/avd/info.c
-+++ b/android/avd/info.c
-@@ -1233,10 +1233,8 @@ _getBuildImagePaths( AvdInfo*  i, AvdInf
-      ** take care of checking the state
-      **/
-     imageLoader_set ( l, AVD_IMAGE_INITSYSTEM );
--    imageLoader_load( l, IMAGE_REQUIRED | IMAGE_DONT_LOCK );
--
--    /* force the system image to read-only status */
--    l->pState[0] = IMAGE_STATE_READONLY;
-+    l->pState[0] = IMAGE_STATE_MUSTLOCK;
-+    imageLoader_load( l, IMAGE_REQUIRED );
- 
-     /** cache partition handling
-      **/
diff --git a/package/goldfish-qemu/skins/HVGA/arrow_down.png b/package/goldfish-qemu/skins/HVGA/arrow_down.png
deleted file mode 100644
index 19b3764e8337ba08cc2910ce9a9b77cae0c29155..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3438
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
Q^8f$<07*qoM6N<$f_jc(fdBvi

diff --git a/package/goldfish-qemu/skins/HVGA/arrow_left.png b/package/goldfish-qemu/skins/HVGA/arrow_left.png
deleted file mode 100644
index 113e58427aca1ebce4bdc7bc671e8e4be09434ad..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4122
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
Y0C2jA^6SYIod5s;07*qoM6N<$f_+T4+5i9m

diff --git a/package/goldfish-qemu/skins/HVGA/arrow_right.png b/package/goldfish-qemu/skins/HVGA/arrow_right.png
deleted file mode 100644
index ffe3356c0ff6dbbd6cab13a5ac76dcf1f8e650d0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4147
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

diff --git a/package/goldfish-qemu/skins/HVGA/arrow_up.png b/package/goldfish-qemu/skins/HVGA/arrow_up.png
deleted file mode 100644
index 81c54df51eaab14555dfe0aec4014c1f4eb2e307..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3493
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
TEP9sB00000NkvXXu0mjfMx=ux

diff --git a/package/goldfish-qemu/skins/HVGA/back.png b/package/goldfish-qemu/skins/HVGA/back.png
deleted file mode 100644
index 41034d9105e4fc077ea8620862828cc0e76c7938..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3564
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

diff --git a/package/goldfish-qemu/skins/HVGA/device.png b/package/goldfish-qemu/skins/HVGA/device.png
deleted file mode 100644
index 465eb029d6d3af07d9df51b71713042d5711c022..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 45511
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
W%$ntMK9COp0000<MNUMnLSTZmtMsn`

diff --git a/package/goldfish-qemu/skins/HVGA/end.png b/package/goldfish-qemu/skins/HVGA/end.png
deleted file mode 100644
index 6830a603beaeca8c21ba80eeda0c157e5d1755e7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3562
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

diff --git a/package/goldfish-qemu/skins/HVGA/home.png b/package/goldfish-qemu/skins/HVGA/home.png
deleted file mode 100644
index 7d021369b8ad4b68fb7653c9e0227348a241c9cf..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3578
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
AmjD0&

diff --git a/package/goldfish-qemu/skins/HVGA/key.png b/package/goldfish-qemu/skins/HVGA/key.png
deleted file mode 100644
index 7a3f563bdeeaee0a604e964edf60cd2facc39b4a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2857
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
Hu0mjf#?nTe

diff --git a/package/goldfish-qemu/skins/HVGA/keyboard.png b/package/goldfish-qemu/skins/HVGA/keyboard.png
deleted file mode 100644
index bb076d315a7e434b7251598693087065e30ccf21..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 11032
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
PS^*6eUFAxI-OK+2E`~%c

diff --git a/package/goldfish-qemu/skins/HVGA/layout b/package/goldfish-qemu/skins/HVGA/layout
deleted file mode 100644
index 4c3d76420f..0000000000
--- a/package/goldfish-qemu/skins/HVGA/layout
+++ /dev/null
@@ -1,380 +0,0 @@
-parts {
-    device {
-        background {
-            image   device.png
-        }
-        display {
-            width   320
-            height  480
-            x       31
-            y       72
-        }
-
-        buttons {
-            soft-left {
-                    image menu.png
-                    x 147
-                    y 555
-            }
-            home {
-                    image home.png
-                    x 48
-                    y 590
-            }
-            back {
-                    image back.png
-                    x 286
-                    y 590
-            }
-            dpad-up {
-                    image arrow_up.png
-                    x 140
-                    y 595
-            }
-            dpad-down {
-                    image arrow_down.png
-                    x 140
-                    y 656
-            }
-            dpad-left {
-                    image arrow_left.png
-                    x 111
-                    y 598
-            }
-            dpad-right {
-                    image arrow_right.png
-                    x 222
-                    y 598
-            }
-            dpad-center {
-                    image select.png
-                    x 142
-                    y 626
-            }
-            phone-dial {
-                    image send.png
-                    x 48
-                    y 646
-            }
-            phone-hangup {
-                    image end.png
-                    x 286
-                    y 646
-            }
-
-            power {
-                    image power.png
-                    x -38
-                    y 52
-            }
-
-            volume-up {
-                    image volume_up.png
-                    x 362
-                    y 260
-            }
-
-            volume-down {
-                    image volume_down.png
-                    x 362
-                    y 310
-            }
-        }
-    }
-
-    keyboard {
-        background {
-            image   keyboard.png
-        }
-        buttons {
-            1 {
-                image  key.png
-                x  0
-                y  0
-            }
-            2 {
-                image  key.png
-                x 37
-                y 0
-            }
-            3 {
-                image  key.png
-                x 74
-                y 0
-            }
-            4 {
-                image  key.png
-                x 111
-                y 0
-            }
-            5 {
-                image  key.png
-                x 148
-                y 0
-            }
-            6 {
-                image  key.png
-                x 185
-                y 0
-            }
-            7 {
-                image  key.png
-                x 222
-                y 0
-            }
-            8 {
-                image  key.png
-                x 259
-                y 0
-            }
-            9 {
-                image  key.png
-                x 296
-                y 0
-            }
-            0 {
-                image  key.png
-                x 333
-                y 0
-            }
-
-            q {
-                image  key.png
-                x  0
-                y  36
-            }
-            w {
-                image  key.png
-                x 37
-                y 36
-            }
-            e {
-                image  key.png
-                x 74
-                y 36
-            }
-            r {
-                image  key.png
-                x 111
-                y 36
-            }
-            t {
-                image  key.png
-                x 148
-                y 36
-            }
-            y {
-                image  key.png
-                x 185
-                y 36
-            }
-            u {
-                image  key.png
-                x 222
-                y 36
-            }
-            i {
-                image  key.png
-                x 259
-                y 36
-            }
-            o {
-                image  key.png
-                x 296
-                y 36
-            }
-            p {
-                image  key.png
-                x 333
-                y 36
-            }
-
-            a {
-                image  key.png
-                x  0
-                y  72
-            }
-            s {
-                image  key.png
-                x 37
-                y 72
-            }
-            d {
-                image  key.png
-                x 74
-                y 72
-            }
-            f {
-                image  key.png
-                x 111
-                y 72
-            }
-            g {
-                image  key.png
-                x 148
-                y 72
-            }
-            h {
-                image  key.png
-                x 185
-                y 72
-            }
-            j {
-                image  key.png
-                x 222
-                y 72
-            }
-            k {
-                image  key.png
-                x 259
-                y 72
-            }
-            l {
-                image  key.png
-                x 296
-                y 72
-            }
-            DEL {
-                image  key.png
-                x 333
-                y 72
-            }
-
-            CAP {
-                image  key.png
-                x  0
-                y  108
-            }
-            z {
-                image  key.png
-                x 37
-                y 108
-            }
-            x {
-                image  key.png
-                x 74
-                y 108
-            }
-            c {
-                image  key.png
-                x 111
-                y 108
-            }
-            v {
-                image  key.png
-                x 148
-                y 108
-            }
-            b {
-                image  key.png
-                x 185
-                y 108
-            }
-            n {
-                image  key.png
-                x 222
-                y 108
-            }
-            m {
-                image  key.png
-                x 259
-                y 108
-            }
-            PERIOD {
-                image  key.png
-                x 296
-                y 108
-            }
-            ENTER {
-                image  key.png
-                x 333
-                y 108
-            }
-
-            ALT {
-                image  key.png
-                x  0
-                y  144
-            }
-            SYM {
-                image  key.png
-                x 37
-                y 144
-            }
-            AT {
-                image  key.png
-                x 74
-                y 144
-            }
-            SPACE {
-                image  spacebar.png
-                x 111
-                y 144
-            }
-            SLASH {
-                image  key.png
-                x 259
-                y 144
-            }
-            COMMA {
-                image  key.png
-                x 296
-                y 144
-            }
-            ALT2 {
-                image  key.png
-                x 333
-                y 144
-            }
-
-        }
-    }
-}
-
-layouts {
-    portrait {
-        width     900
-        height    730
-        color     0xe0e0e0
-        event     EV_SW:0:1
-
-        part1 {
-            name    device
-            x       40
-            y       -18
-        }
-        part2 {
-            name    keyboard
-            x       480
-            y       200
-        }
-    }
-
-    landscape {
-        width     900
-        height    670
-        color     0xe0e0e0
-        event     EV_SW:0:0
-
-        part1 {
-            name      device
-            x         50
-            y         440
-            rotation  3
-        }
-        part2 {
-            name     keyboard
-            x        250
-            y        470
-        }
-    }
-}
-
-keyboard {
-    charmap qwerty2
-}
-
-network {
-    speed  full
-    delay  none
-}
diff --git a/package/goldfish-qemu/skins/HVGA/menu.png b/package/goldfish-qemu/skins/HVGA/menu.png
deleted file mode 100644
index e81d8abcffd3f8eaf515449e27b8f9c8480ca323..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3079
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
VJZ~&LN|^uv002ovPDHLkV1i@ZvyuP+

diff --git a/package/goldfish-qemu/skins/HVGA/power.png b/package/goldfish-qemu/skins/HVGA/power.png
deleted file mode 100644
index 5894288f03c02adba38cabe64b76131b33b5ba77..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3782
zcmV;%4mt6OP)<h;3K|Lk000e1NJLTq0024w002V}1^@s6od(Kc00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc@_vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z@C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z@488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6@fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*SAPZv|vv@2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w@D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+@AhPrP6BK<z=<L*0kfKU@CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000B=Nkl<Zc-rh;KTK0W94^EKR2Gaz1B+-~Oj^fQU2G%{m`F^RNMJLv7B&+lF%AlA
zajd2jiP5AE2E|S4CPWtM9|njCMjRB&Scki>&0YI=ukBGDci*@CXdn0P{qF1U{(kqa
zqg*bR%jF1R369{8D_3*5Z(ms;D*Ap3dtpY{?p$m4D~$@fHYx1p$$cZ#ZS)QboBA$n
zVnrixK-&9;GJGis{wHi9ChX!_VYe4ZXj8a(M%ba-+J#(u^2ZM*H6^Y5{`IP``5z>7
zPjtxwOdk`re=D5NIV5X>*ePLWcZA&?^-J05R$KUJINU_)z;oic;fJ$?A|l6^%yeoF
z3f-C?T{%YyMFAX^hzuIB@XHxO<8f(YmiiY{{j{FYkpVaQ2DN@#Mrd?K9ap+Ceum%H
z5gLE$=6Jg5x1|y48mx^_TY9t2``sBKtO5zOtm-A9j8KAv5+sxe6``(<2dyJC-6QRB
zVaJwO#D|*D=o9txi5o0pwxI+GC7L7@(uXl$Da77LthSb(@IpY<AH+%NqryVt@_Sm?
ze1pB;@ejg6f0~i^H!nP9ga#rKxb~&7>>y+Yut1CZ`>WcBmI$4=Tc5}csTX}X+*o$`
z2WomiSG5s_2}K*HOF1?);cugoeN?Gl>9MYd{0T#ZraZPS&CBoo72JCR>GRX|ug5c_
z#wels%0D8rIB7Qf!o~WLYODOR?Sy*G!I~yg$M#!N(bjS3ZYdx!3oO!5jYBJhXxr<e
zJHc+3nG^O>T-Z-&i+#qIUC-qoTcpHjgo4nL*6G2dyPtp=y;$sP^qVNa{k+<2!cdi4
z@aU9`oHLvK_{aL+uS}2{ql98>xE`tKeYU#JiS+t%8}fVinA8|06jks1dj0Fk&%$Cs
zyLK0p_Ct`@@4Zsf*Nk)5&5U!|De@U7_RFdk?*h=<)@acDJUTtu%W8haJ`Y<kLo_#M
zW_W`1vwulsTO(A*^0I0Za_TPnM_4b($*(tRX9wvcFG#_G66#eY7ySM)$)XNbl}nIN
zf`k$zlpvublpvu52_;A<p`$oSLK&f9hO3&Us^69ox|Vj6(5l~-5nAkVwC(J%lu)ex
zlpIk!z|ZP>vZbA(_vhUpwAN2c35AT*RyipAsyzn8@?lFhX;&2tKe9<jCl(;|_EIk%
zHoy;W0lOmy@u1VN8y9v=z7inp$9^CppGj5Z@*T$}7W@El8g`x+r$RamnNpv#BC7L+
zqi3I0WTf(QLPh{KI=B1H*y!XeO8s*|swg83&wTN8LZwQEdJ!-0z%IJJTWS^EdtKVW
wU{&VkY4vkap1o%N*vSqa2x}KesAc#+0JESF*}TU^H2?qr07*qoM6N<$g5=mAC;$Ke

diff --git a/package/goldfish-qemu/skins/HVGA/select.png b/package/goldfish-qemu/skins/HVGA/select.png
deleted file mode 100644
index 803d49315900333c6db766d1abe9300ed727ffb6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3374
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
Ef()rXApigX

diff --git a/package/goldfish-qemu/skins/HVGA/send.png b/package/goldfish-qemu/skins/HVGA/send.png
deleted file mode 100644
index f547c8817d94f53f9ee304b701ccfc76da062783..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3561
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

diff --git a/package/goldfish-qemu/skins/HVGA/spacebar.png b/package/goldfish-qemu/skins/HVGA/spacebar.png
deleted file mode 100644
index 19fe604765b984dd1df424c25b9ba0c42f678276..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2916
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

diff --git a/package/goldfish-qemu/skins/HVGA/volume_down.png b/package/goldfish-qemu/skins/HVGA/volume_down.png
deleted file mode 100644
index f8a88dec810c5e3a33ba6d1c1919acb00fa97feb..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3586
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
IM6N<$f_nU^82|tP

diff --git a/package/goldfish-qemu/skins/HVGA/volume_up.png b/package/goldfish-qemu/skins/HVGA/volume_up.png
deleted file mode 100644
index 940457f707bdc589883be0d8fd7c49930195a23e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3856
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
S8{H=W0000<MNUMnLSTY0^)aRZ

diff --git a/package/libipfix/Makefile b/package/libipfix/Makefile
deleted file mode 100644
index e4c9315910..0000000000
--- a/package/libipfix/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-# 
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=libipfix
-PKG_VERSION:=r51
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME).$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
-PKG_MD5SUM:=0e5b2871ea20ac48eda3f6006c5dba28
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME).$(PKG_VERSION)
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/libipfix
-  SECTION:=libs
-  CATEGORY:=Libraries
-  TITLE:=IP Flow Information Export Library
-  URL:=http://www.fokus.fraunhofer.de/de/net/more_about/download/ipfixlib.html
-  BUILDONLY:=1
-endef
-
-TARGET_CFLAGS += \
-	-ffunction-sections -fdata-sections
-
-define Build/Compile
-	$(MAKE) -C $(PKG_BUILD_DIR) \
-		CCOPT="$(TARGET_CFLAGS) -I$(BUILD_DIR)/linux/include" \
-		prefix="$(PKG_INSTALL_DIR)/usr" \
-		exec_prefix="$(PKG_INSTALL_DIR)/usr" \
-		all install
-	$(TARGET_CROSS)ranlib $(PKG_INSTALL_DIR)/usr/lib/libipfix.a
-	$(TARGET_CROSS)ranlib $(PKG_INSTALL_DIR)/usr/lib/libipfixmisc.a
-endef
-
-define Build/InstallDev
-	$(INSTALL_DIR) $(1)
-	$(CP) $(PKG_INSTALL_DIR)/* $(1)/
-endef
-
-$(eval $(call BuildPackage,libipfix))
diff --git a/package/libipfix/extra/append-wprobe-ie.pl b/package/libipfix/extra/append-wprobe-ie.pl
deleted file mode 100644
index 8bb658bbb9..0000000000
--- a/package/libipfix/extra/append-wprobe-ie.pl
+++ /dev/null
@@ -1,38 +0,0 @@
-use strict;
-
-my @fields = (
-	[ "_n", "UINT", " - Number of samples", 4 ],
-	[ "_s", "UINT", " - Sum of samples", 8 ],
-	[ "_ss", "UINT", " - Sum of squared samples", 8 ],
-);
-
-my $file = $ARGV[0] or die "Syntax: $0 <file> <start>\n";
--f $file or die "File not found\n";
-my $start = $ARGV[1];
-$start =~ /^\d+$/ or die "Invalid start number";
-open FILE, "<$file" or die "Can't open file";
-while (<FILE>) {
-	/^(%?)(\w+),\s*(\w+),\s*(.+)$/ and do {
-		my $counter = $1;
-		my $rfield = $2;
-		my $nfield = $3;
-		my $descr = $4;
-		my @f;
-		if ($counter) {
-			@f = [ "", "UINT", "", 4];
-		} else {
-			@f = @fields;
-		}
-		foreach my $f (@f) {
-			my $nr = $start++;
-			my $n = $f->[0];
-			my $N = uc $n;
-			my $ftype = $f->[1];
-			my $fdesc = $f->[2];
-			my $size = $f->[3];
-			print "$nr, IPFIX_FT_WPROBE_$rfield$N, $size, IPFIX_CODING_$ftype, \"$nfield$n\", \"$descr$fdesc\"\n";
-		}
-	};
-}
-close FILE;
-
diff --git a/package/libipfix/extra/wprobe-ie.txt b/package/libipfix/extra/wprobe-ie.txt
deleted file mode 100644
index 26d64d2139..0000000000
--- a/package/libipfix/extra/wprobe-ie.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-NOISE, global_noise, wprobe global noice floor
-PHY_BUSY, global_phy_busy, wprobe global airtime total
-PHY_RX, global_phy_rx, wprobe global airtime total from rx-frame
-PHY_TX, global_phy_tx, wprobe global airtime total from tx-frame
-RSSI, link_rssi, wprobe link received signal strength indication
-SIGNAL, link_signal, wprobe link signal strength in dB
-IEEE_RX_RATE, link_ieee_rx_rate, wprobe link IEEE 802.11 RX data rate
-IEEE_TX_RATE, link_ieee_tx_rate, wprobe link IEEE 802.11 TX data rate
-RETRANSMIT_200, link_retransmit_200, wprobe link total retransmissions per packet - <200 bytes
-RETRANSMIT_400, link_retransmit_400, wprobe link total retransmissions per packet - <400 bytes
-RETRANSMIT_800, link_retransmit_800, wprobe link total retransmissions per packet - <800 bytes
-RETRANSMIT_1600, link_retransmit_1600, wprobe link total retransmissions per packet - >800 bytes
-%FRAMES, global_frames, wprobe global number of 802.11 frames seen
-%PROBEREQ, global_probereq, wprobe global number of 802.11 probe requests seen
diff --git a/package/libipfix/patches/100-openimp_sync.patch b/package/libipfix/patches/100-openimp_sync.patch
deleted file mode 100644
index 5b6e2e3793..0000000000
--- a/package/libipfix/patches/100-openimp_sync.patch
+++ /dev/null
@@ -1,474 +0,0 @@
---- a/lib/ipfix.c
-+++ b/lib/ipfix.c
-@@ -37,6 +37,9 @@ $$LIC$$
- #ifdef SCTPSUPPORT
- #include <netinet/sctp.h>
- #endif
-+#ifndef NOTHREADS
-+#include <pthread.h>
-+#endif
- #include <fcntl.h>
- #include <netdb.h>
- 
-@@ -123,6 +126,18 @@ static uint16_t           g_lasttid;    
- static ipfix_datarecord_t g_data = { NULL, NULL, 0 }; /* ipfix_export */
- 
- static ipfix_field_t      *g_ipfix_fields;
-+#ifndef NOTHREADS
-+static pthread_mutex_t    g_mutex;
-+#define mod_lock()        { \
-+                            if ( pthread_mutex_lock( &g_mutex ) !=0 ) \
-+                                mlogf( 0, "[ipfix] mutex_lock() failed: %s\n", \
-+                                       strerror( errno ) ); \
-+                          }
-+#define mod_unlock()      {  pthread_mutex_unlock( &g_mutex ); }
-+#else
-+#define mod_lock()
-+#define mod_unlock()
-+#endif
- 
- /*----- prototypes -------------------------------------------------------*/
- 
-@@ -133,6 +148,7 @@ int  _ipfix_send_message( ipfix_t *ifh, 
-                           ipfix_message_t *message );
- int  _ipfix_write_msghdr( ipfix_t *ifh, ipfix_message_t *msg, iobuf_t *buf );
- void _ipfix_disconnect( ipfix_collector_t *col );
-+int  _ipfix_export_flush( ipfix_t *ifh );
- 
- 
- /* name      : do_writeselect
-@@ -576,16 +592,18 @@ int ipfix_decode_float( void *in, void *
- 
- int ipfix_snprint_float( char *str, size_t size, void *data, size_t len )
- {
--    float tmp32;
--    double tmp64;
-+    uint32_t tmp32;
-+    uint64_t tmp64;
- 
-     switch ( len ) {
-       case 4:
--          ipfix_decode_float( data, &tmp32, 4);
--          return snprintf( str, size, "%f", tmp32 );
-+          memcpy( &tmp32, data, len );
-+          tmp32 = htonl( tmp32 );
-+          return snprintf( str, size, "%f", (float)tmp32 );
-       case 8:
--          ipfix_decode_float( data, &tmp64, 8);
--          return snprintf( str, size, "%lf", tmp64);
-+          memcpy( &tmp64, data, len );
-+          tmp64 = HTONLL( tmp64 );
-+          return snprintf( str, size, "%lf", (double)tmp64 );
-       default:
-           break;
-     }
-@@ -682,12 +700,19 @@ int ipfix_get_eno_ieid( char *field, int
-  * parameters:
-  * remarks:     init module, read field type info.
-  */
--int ipfix_init ( void )
-+int ipfix_init( void )
- {
-     if ( g_tstart ) {
-         ipfix_cleanup();
-     }
- 
-+#ifndef NOTHREADS
-+    if ( pthread_mutex_init( &g_mutex, NULL ) !=0 ) {
-+        mlogf( 0, "[ipfix] pthread_mutex_init() failed: %s\n",
-+               strerror(errno) );
-+        return -1;
-+    }
-+#endif
-     g_tstart = time(NULL);
-     signal( SIGPIPE, SIG_IGN );
-     g_lasttid = 255;
-@@ -806,6 +831,9 @@ void ipfix_cleanup ( void )
-     g_data.maxfields = 0;
-     g_data.lens  = NULL;
-     g_data.addrs = NULL;
-+#ifndef NOTHREADS
-+    (void)pthread_mutex_destroy( &g_mutex );
-+#endif
- }
- 
- int _ipfix_connect ( ipfix_collector_t *col )
-@@ -1465,7 +1493,7 @@ int _ipfix_write_template( ipfix_t      
-       default:
-           /* check space */
-           if ( tsize+ifh->offset > IPFIX_DEFAULT_BUFLEN ) {
--              if ( ipfix_export_flush( ifh ) < 0 )
-+              if ( _ipfix_export_flush( ifh ) < 0 )
-                   return -1;
-               if ( tsize+ifh->offset > IPFIX_DEFAULT_BUFLEN )
-                   return -1;
-@@ -1474,6 +1502,8 @@ int _ipfix_write_template( ipfix_t      
-           /* write template prior to data */
-           if ( ifh->offset > 0 ) {
-               memmove( ifh->buffer + tsize, ifh->buffer, ifh->offset );
-+              if ( ifh->cs_tid )
-+                  ifh->cs_header += tsize;
-           }
- 
-           buf = ifh->buffer;
-@@ -1615,8 +1645,11 @@ int ipfix_open( ipfix_t **ipfixh, int so
-         return -1;
-     }
-     node->ifh   = i;
-+
-+    mod_lock();
-     node->next  = g_ipfixlist;
-     g_ipfixlist = node;
-+    mod_unlock();
- 
-     *ipfixh = i;
-     return 0;
-@@ -1633,7 +1666,8 @@ void ipfix_close( ipfix_t *h )
-     {
-         ipfix_node_t *l, *n;
- 
--        ipfix_export_flush( h );
-+        mod_lock();
-+        _ipfix_export_flush( h );
- 
-         while( h->collectors )
-             _ipfix_drop_collector( (ipfix_collector_t**)&h->collectors );
-@@ -1659,6 +1693,7 @@ void ipfix_close( ipfix_t *h )
- #endif
-         free(h->buffer);
-         free(h);
-+        mod_unlock();
-     }
- }
- 
-@@ -2156,6 +2191,22 @@ void ipfix_release_template( ipfix_t *if
-     ipfix_delete_template( ifh, templ );
- }
- 
-+static void _finish_cs( ipfix_t *ifh )
-+{
-+    size_t   buflen;
-+    uint8_t  *buf;
-+
-+    /* finish current dataset */
-+    if ( (buf=ifh->cs_header) ==NULL )
-+        return;
-+    buflen = 0;
-+    INSERTU16( buf+buflen, buflen, ifh->cs_tid );
-+    INSERTU16( buf+buflen, buflen, ifh->cs_bytes );
-+    ifh->cs_bytes = 0;
-+    ifh->cs_header = NULL;
-+    ifh->cs_tid = 0;
-+}
-+
- int ipfix_export( ipfix_t *ifh, ipfix_template_t *templ, ... )
- {
-     int       i;
-@@ -2199,13 +2250,14 @@ int ipfix_export( ipfix_t *ifh, ipfix_te
-                                g_data.addrs, g_data.lens );
- }
- 
--int ipfix_export_array( ipfix_t          *ifh,
--                        ipfix_template_t *templ,
--                        int              nfields,
--                        void             **fields,
--                        uint16_t         *lengths )
-+static int
-+_ipfix_export_array( ipfix_t          *ifh,
-+                     ipfix_template_t *templ,
-+                     int              nfields,
-+                     void             **fields,
-+                     uint16_t         *lengths )
- {
--    int               i;
-+    int               i, newset_f=0;
-     size_t            buflen, datasetlen;
-     uint8_t           *p, *buf;
- 
-@@ -2249,7 +2301,19 @@ int ipfix_export_array( ipfix_t         
- 
-     /** get size of data set, check space
-      */
--    for ( i=0, datasetlen=4; i<nfields; i++ ) {
-+    if ( templ->tid == ifh->cs_tid ) {
-+        newset_f = 0;
-+        datasetlen = 0;
-+    }
-+    else {
-+        if ( ifh->cs_tid > 0 ) {
-+            _finish_cs( ifh );
-+        }
-+        newset_f = 1;
-+        datasetlen = 4;
-+    }
-+
-+    for ( i=0; i<nfields; i++ ) {
-         if ( templ->fields[i].flength == IPFIX_FT_VARLEN ) {
-             if ( lengths[i]>254 )
-                 datasetlen += 3;
-@@ -2263,21 +2327,29 @@ int ipfix_export_array( ipfix_t         
-         }
-         datasetlen += lengths[i];
-     }
--    if ( ((ifh->offset + datasetlen) > IPFIX_DEFAULT_BUFLEN )
--         && (ipfix_export_flush( ifh ) <0) ) {
--        return -1;
-+
-+    if ( (ifh->offset + datasetlen) > IPFIX_DEFAULT_BUFLEN ) {
-+        if ( ifh->cs_tid )
-+            _finish_cs( ifh );
-+        newset_f = 1;
-+
-+        if ( _ipfix_export_flush( ifh ) <0 )
-+            return -1;
-     }
- 
--    /* fill buffer
--     */
-+    /* fill buffer */
-     buf    = (uint8_t*)(ifh->buffer) + ifh->offset;
-     buflen = 0;
- 
--    /* insert data set
--     */
--    ifh->nrecords ++;
--    INSERTU16( buf+buflen, buflen, templ->tid );
--    INSERTU16( buf+buflen, buflen, datasetlen );
-+    if ( newset_f ) {
-+        /* insert data set
-+         */
-+        ifh->cs_bytes = 0;
-+        ifh->cs_header = buf;
-+        ifh->cs_tid = templ->tid;
-+        INSERTU16( buf+buflen, buflen, templ->tid );
-+        INSERTU16( buf+buflen, buflen, 4 );
-+    }
- 
-     /* insert data record
-      */
-@@ -2303,7 +2375,9 @@ int ipfix_export_array( ipfix_t         
-         buflen += lengths[i];
-     }
- 
-+    ifh->nrecords ++;
-     ifh->offset += buflen;
-+    ifh->cs_bytes += buflen;
-     if ( ifh->version == IPFIX_VERSION )
-         ifh->seqno ++;
-     return 0;
-@@ -2313,7 +2387,7 @@ int ipfix_export_array( ipfix_t         
-  * parameters:
-  * remarks:     rewrite this func!
-  */
--int ipfix_export_flush( ipfix_t *ifh )
-+int _ipfix_export_flush( ipfix_t *ifh )
- {
-     iobuf_t           *buf;
-     ipfix_collector_t *col;
-@@ -2322,8 +2396,14 @@ int ipfix_export_flush( ipfix_t *ifh )
-     if ( (ifh==NULL) || (ifh->offset==0) )
-         return 0;
- 
--    if ( (buf=_ipfix_getbuf()) ==NULL )
-+    if ( ifh->cs_tid > 0 ) {
-+        /* finish current dataset */
-+        _finish_cs( ifh );
-+    }
-+
-+    if ( (buf=_ipfix_getbuf()) ==NULL ) {
-         return -1;
-+    }
- 
- #ifdef DEBUG
-     mlogf( 0, "[ipfix_export_flush] msg has %d records, %d bytes\n",
-@@ -2350,3 +2430,30 @@ int ipfix_export_flush( ipfix_t *ifh )
-     _ipfix_freebuf( buf );
-     return ret;
- }
-+
-+int ipfix_export_array( ipfix_t          *ifh,
-+                        ipfix_template_t *templ,
-+                        int              nfields,
-+                        void             **fields,
-+                        uint16_t         *lengths )
-+{
-+    int ret;
-+
-+    mod_lock();
-+    ret = _ipfix_export_array( ifh, templ, nfields, fields, lengths );
-+    mod_unlock();
-+
-+    return ret;
-+}
-+
-+int ipfix_export_flush( ipfix_t *ifh )
-+{
-+    int ret;
-+
-+    mod_lock();
-+    ret = _ipfix_export_flush( ifh );
-+    mod_unlock();
-+
-+    return ret;
-+}
-+
---- a/lib/ipfix.h
-+++ b/lib/ipfix.h
-@@ -142,6 +142,12 @@ typedef struct
-     int         nrecords;         /* no. of records in buffer */
-     size_t      offset;           /* output buffer fill level */
-     uint32_t    seqno;            /* sequence no. of next message */
-+
-+    /* experimental */
-+    int        cs_tid;            /* template id of current dataset */
-+    int        cs_bytes;          /* size of current set */
-+    uint8_t    *cs_header;        /* start of current set */
-+
- } ipfix_t;
- 
- /** exporter funcs
---- a/lib/ipfix_col.c
-+++ b/lib/ipfix_col.c
-@@ -897,6 +897,8 @@ int ipfix_decode_datarecord( ipfixt_node
-             return -1;
-         }
- 
-+        n->ipfixt->fields[i].elem->decode(p,p,len);
-+
-         data->lens[i]  = len;
-         data->addrs[i] = p;
- 
-@@ -907,7 +909,7 @@ int ipfix_decode_datarecord( ipfixt_node
-     return 0;
- }
- 
--static void do_free_datarecord( ipfix_datarecord_t   *data )
-+void ipfix_free_datarecord( ipfix_datarecord_t   *data )
- { 
-     if ( data ) {
-         if ( data->addrs )
-@@ -925,6 +927,7 @@ int ipfix_parse_msg( ipfix_input_t *inpu
-     ipfix_hdr_t          hdr;                  /* ipfix packet header */
-     ipfixs_node_t        *s;
-     ipfix_datarecord_t   data = { NULL, NULL, 0 };
-+    ipfixe_node_t        *e;
-     uint8_t              *buf;                 /* ipfix payload */
-     uint16_t             setid, setlen;        /* set id, set lenght */
-     int                  i, nread, offset;     /* counter */
-@@ -1042,6 +1045,12 @@ int ipfix_parse_msg( ipfix_input_t *inpu
-                 err_flag = 1;
-             } 
-             else {
-+                for ( e=g_exporter; e!=NULL; e=e->next ) {
-+                    if ( e->elem->export_dset )
-+                        (void) e->elem->export_dset( t, buf+nread, setlen,
-+                                                     e->elem->data );
-+                }
-+
-                 /** read data records
-                  */
-                 for ( offset=nread, bytesleft=setlen; bytesleft>4; ) {
-@@ -1076,11 +1085,11 @@ int ipfix_parse_msg( ipfix_input_t *inpu
-         goto errend;
- 
-  end:
--    do_free_datarecord( &data );
-+    ipfix_free_datarecord( &data );
-     return nread;
- 
-  errend:
--    do_free_datarecord( &data );
-+    ipfix_free_datarecord( &data );
-     return -1;
- }
- 
-@@ -1093,7 +1102,7 @@ void process_client_tcp( int fd, int mas
-     tcp_conn_t   *tcon = (tcp_conn_t*)data;
-     char         *func = "process_client_tcp";
- 
--    mlogf( 3,  "[%s] fd %d mask %d called.\n", func, fd, mask );
-+    mlogf( 4,  "[%s] fd %d mask %d called.\n", func, fd, mask );
- 
-     /** read ipfix header 
-      */
---- a/lib/ipfix_col.h
-+++ b/lib/ipfix_col.h
-@@ -88,6 +88,7 @@ typedef struct ipfix_col_info
-     int (*export_newsource)(ipfixs_node_t*,void*);
-     int (*export_newmsg)(ipfixs_node_t*,ipfix_hdr_t*,void*);
-     int (*export_trecord)(ipfixs_node_t*,ipfixt_node_t*,void*);
-+    int (*export_dset)(ipfixt_node_t*,uint8_t*,size_t,void*);
-     int (*export_drecord)(ipfixs_node_t*,ipfixt_node_t*,
-                           ipfix_datarecord_t*,void*);
-     void (*export_cleanup)(void*);
---- a/lib/ipfix_col_files.c
-+++ b/lib/ipfix_col_files.c
-@@ -68,7 +68,7 @@ static int export_newsource_file( ipfixs
-             return -1;
-         }
-         snprintf( s->fname+strlen(s->fname), PATH_MAX-strlen(s->fname),
--                  "/%u", s->odid );
-+                  "/%u", (unsigned int)s->odid );
-         if ( (access( s->fname, R_OK ) <0 )
-              && (mkdir( s->fname, S_IRWXU ) <0) ) {
-             mlogf( 0, "[%s] cannot access dir '%s': %s\n",
---- a/lib/ipfix_FOKUS_IEs.txt
-+++ b/lib/ipfix_FOKUS_IEs.txt
-@@ -24,6 +24,8 @@
- 196, IPFIX_FT_PKTID,                4, IPFIX_CODING_UINT, "pktId", "FOKUS packet id"
- 197, IPFIX_FT_STARTTIME,            4, IPFIX_CODING_INT, "startTime", "FOKUS interval start"
- 198, IPFIX_FT_ENDTIME,              4, IPFIX_CODING_INT, "endTime", "FOKUS interval end"
-+199, IPFIX_FT_RTT_USEC,             8, IPFIX_CODING_UINT, "rtt_usec", "FOKUS rtt in us"
-+
- 300, IPFIX_FT_FLOWCREATIONTIMEUSEC, 4, IPFIX_CODING_INT, "flowCreationTimeUsec", "FOKUS flow start usec fraction"
- 301, IPFIX_FT_FLOWENDTIMEUSEC,      4, IPFIX_CODING_INT, "flowEndTimeUsec", "FOKUS flow end usec fraction"
- 303, IPFIX_FT_TC_PACKETS,           4, IPFIX_CODING_UINT, "tcPackets", "DAIDALOS Packets seen"
-@@ -39,3 +41,48 @@
- 313, IPFIX_FT_OWDVARMIN_NSEC,       4, IPFIX_CODING_INT, "owdvarmin_nsec", "FOKUS minimum owd variance in ns"
- 314, IPFIX_FT_OWDVARMAX_NSEC,       4, IPFIX_CODING_INT, "owdvarmax_nsec", "FOKUS maximum ow variance in ns"
- 
-+# Project INTERSECTION
-+315, IPFIX_FT_SOURCEIPV4FANOUT,     4, IPFIX_CODING_UINT,"sourceIPv4FanOut", "FOKUS IPv4 fanout"
-+316, IPFIX_FT_DESTINATIONIPV4FANIN, 4, IPFIX_CODING_UINT,"destinationIPv4FanIn", "FOKUS IPv4 fanin"
-+
-+# Project PRISM
-+
-+330, IPFIX_FT_PR_SESSIONID,	4, IPFIX_CODING_UINT, "sessionId", "PRISM Session ID"
-+331, IPFIX_FT_PR_TRANSACTIONID, 4, IPFIX_CODING_UINT, "transactionId", "PRISM Transaction ID"
-+332, IPFIX_FT_PR_ENCRYPTEDDATA, 65535, IPFIX_CODING_STRING, "encryptedData", "PRISM encrypted data"
-+333, IPFIX_FT_PR_DECRYPTIONKEY, 65535, IPFIX_CODING_STRING, "decryptionKey", "PRISM decryption key"
-+334, IPFIX_FT_PR_KEYSHARE,      65535, IPFIX_CODING_STRING, "keyShare", "PRISM key share"
-+335, IPFIX_FT_PR_KEYSHAREADP,   65535, IPFIX_CODING_STRING, "keyShareAdp", "PRISM key share ADP"
-+336, IPFIX_FT_PR_INITVECTOR,    65535, IPFIX_CODING_STRING, "cryptoInitVector", "PRISM crypto init vector"
-+
-+
-+# these information elements have been defined by FOKUS for the Oracle project
-+
-+402, IPFIX_FT_ORsignalBandwidth, 4, IPFIX_CODING_UINT, "ORsignalBandwidth", "signal bandwidth" 
-+403, IPFIX_FT_ORsignalPower, 2, IPFIX_CODING_UINT, "ORsignalPower", "ERIP" 
-+404, IPFIX_FT_ORmodulationType, 2, IPFIX_CODING_UINT, "ORmodulationType", "AM/FM,.."
-+405, IPFIX_FT_ORsymbolRate, 2, IPFIX_CODING_UINT, "ORsymbolRate", "symbol rate"
-+406, IPFIX_FT_ORmodulationOrder, 1, IPFIX_CODING_UINT, "ORmodulationOrder", "number of levels"
-+407, IPFIX_FT_ORrolloffFactor, 2, IPFIX_CODING_UINT, "ORrolloffFactor", "roll of factor"
-+408, IPFIX_FT_ORgeopositionLon, 4, IPFIX_CODING_UINT, "ORgeopositionLon", "GPS coordinate, resolution 1 cm"
-+409, IPFIX_FT_ORgeopositionLat, 4, IPFIX_CODING_UINT, "ORgeopositionLat", "GPS coordinate, resolution 1 cm"
-+410, IPFIX_FT_ORgeopositionElev, 4, IPFIX_CODING_UINT, "ORgeopositionElev", "GPS coordinate, resolution 1 cm"
-+411, IPFIX_FT_ORpolicyRecord, 65535, IPFIX_CODING_STRING, "ORpolicyRecord", "policy record has variable length, First 8 bits in data describe the length (in bytes) of the field"
-+420, IPFIX_FT_channel_status, 1, IPFIX_CODING_UINT, "channel_status", vacancy of the scanned channel (1: channel busy, 0: channel idle)"
-+421, IPFIX_FT_sensing_value, 2, IPFIX_CODING_UINT, "sensing_value", "Cost function output"
-+422, IPFIX_FT_sensing_threshold, 2, IPFIX_CODING_UINT, "sensing_threshold", "Decision threshold"
-+423, IPFIX_FT_OR_terminal_id, 1, IPFIX_CODING_UINT, "OR_terminal_id", "terminal identifier"
-+424, IPFIX_FT_OR_terminal_id_list, 65535, IPFIX_CODING_STRING, "OR_terminal_id_list", "terminal identifier list"
-+425, IPFIX_FT_Infrastructure_network_id, 1, IPFIX_CODING_UINT, "Infrastructure_network_id", "network identifier"
-+426, IPFIX_FT_Infrastructure_network_type, 1, IPFIX_CODING_UINT, "Infrastructure_network_type", "network type (GSM - 1, UMTS - 2, WiMAX - 3, WiFi - 4)" 
-+427, IPFIX_FT_Battery_lifetime_min, 1, IPFIX_CODING_UINT, "Battery_lifetime_min", "expected battery lifetime to provide requested services or functionalities, in minutes"
-+428, IPFIX_FT_Battery_lifetime_h, 1, IPFIX_CODING_UINT, "Battery_lifetime_h", "expected battery lifetime to provide requested services or functionalities, in hours"
-+429, IPFIX_FT_Battery_status, 1, IPFIX_CODING_UINT, "Battery_status", "expected battery lifetime to provide requested services or functionalities, 1 bit status flag, values 1 or 0"
-+430, IPFIX_FT_Cell_id_number, 4, IPFIX_CODING_UINT, "Cell_id_number", "16-32 bit cell id number, identifier"
-+431, IPFIX_FT_Spectral_allocation_vector, 1, IPFIX_CODING_UINT, "Spectral_allocation_vector", "binary vector to indicate whether a band is free 1 bit 0 or not 1 bit 1"
-+432, IPFIX_FT_Spectral_allocation_profile, 2, IPFIX_CODING_UINT, "Spectral_allocation_profile", "received power spectral density vs. frequency to indicate spectral activity in the band of interest (8-16 bits per discrete frequency value)"
-+433, IPFIX_FT_Center_frequency, 2, IPFIX_CODING_UINT, "Center_frequency", "Center frequency of the sensed band"
-+434, IPFIX_FT_Bandwidth_of_CAP, 2, IPFIX_CODING_UINT, "Bandwidth_of_CAP", "Bandwidth of the spectral allocation profile"
-+435, IPFIX_FT_ORmodulation, 1, IPFIX_CODING_UINT, "ORmodulation", "CREST factor"
-+436, IPFIX_FT_ORprofileRecord, 65535, IPFIX_CODING_STRING, "ORprofileRecord", "profile record has variable length, First 8 bits in data describe the length (in bytes) of the field"
-+
diff --git a/package/libipfix/patches/110-wprobe_ie.patch b/package/libipfix/patches/110-wprobe_ie.patch
deleted file mode 100644
index 5e37280814..0000000000
--- a/package/libipfix/patches/110-wprobe_ie.patch
+++ /dev/null
@@ -1,44 +0,0 @@
---- a/lib/ipfix_FOKUS_IEs.txt
-+++ b/lib/ipfix_FOKUS_IEs.txt
-@@ -86,3 +86,41 @@
- 435, IPFIX_FT_ORmodulation, 1, IPFIX_CODING_UINT, "ORmodulation", "CREST factor"
- 436, IPFIX_FT_ORprofileRecord, 65535, IPFIX_CODING_STRING, "ORprofileRecord", "profile record has variable length, First 8 bits in data describe the length (in bytes) of the field"
- 
-+500, IPFIX_FT_WPROBE_NOISE_N, 4, IPFIX_CODING_UINT, "global_noise_n", "wprobe global noice floor - Number of samples"
-+501, IPFIX_FT_WPROBE_NOISE_S, 8, IPFIX_CODING_UINT, "global_noise_s", "wprobe global noice floor - Sum of samples"
-+502, IPFIX_FT_WPROBE_NOISE_SS, 8, IPFIX_CODING_UINT, "global_noise_ss", "wprobe global noice floor - Sum of squared samples"
-+503, IPFIX_FT_WPROBE_PHY_BUSY_N, 4, IPFIX_CODING_UINT, "global_phy_busy_n", "wprobe global airtime total - Number of samples"
-+504, IPFIX_FT_WPROBE_PHY_BUSY_S, 8, IPFIX_CODING_UINT, "global_phy_busy_s", "wprobe global airtime total - Sum of samples"
-+505, IPFIX_FT_WPROBE_PHY_BUSY_SS, 8, IPFIX_CODING_UINT, "global_phy_busy_ss", "wprobe global airtime total - Sum of squared samples"
-+506, IPFIX_FT_WPROBE_PHY_RX_N, 4, IPFIX_CODING_UINT, "global_phy_rx_n", "wprobe global airtime total from rx-frame - Number of samples"
-+507, IPFIX_FT_WPROBE_PHY_RX_S, 8, IPFIX_CODING_UINT, "global_phy_rx_s", "wprobe global airtime total from rx-frame - Sum of samples"
-+508, IPFIX_FT_WPROBE_PHY_RX_SS, 8, IPFIX_CODING_UINT, "global_phy_rx_ss", "wprobe global airtime total from rx-frame - Sum of squared samples"
-+509, IPFIX_FT_WPROBE_PHY_TX_N, 4, IPFIX_CODING_UINT, "global_phy_tx_n", "wprobe global airtime total from tx-frame - Number of samples"
-+510, IPFIX_FT_WPROBE_PHY_TX_S, 8, IPFIX_CODING_UINT, "global_phy_tx_s", "wprobe global airtime total from tx-frame - Sum of samples"
-+511, IPFIX_FT_WPROBE_PHY_TX_SS, 8, IPFIX_CODING_UINT, "global_phy_tx_ss", "wprobe global airtime total from tx-frame - Sum of squared samples"
-+512, IPFIX_FT_WPROBE_RSSI_N, 4, IPFIX_CODING_UINT, "link_rssi_n", "wprobe link received signal strength indication - Number of samples"
-+513, IPFIX_FT_WPROBE_RSSI_S, 8, IPFIX_CODING_UINT, "link_rssi_s", "wprobe link received signal strength indication - Sum of samples"
-+514, IPFIX_FT_WPROBE_RSSI_SS, 8, IPFIX_CODING_UINT, "link_rssi_ss", "wprobe link received signal strength indication - Sum of squared samples"
-+515, IPFIX_FT_WPROBE_SIGNAL_N, 4, IPFIX_CODING_UINT, "link_signal_n", "wprobe link signal strength in dB - Number of samples"
-+516, IPFIX_FT_WPROBE_SIGNAL_S, 8, IPFIX_CODING_UINT, "link_signal_s", "wprobe link signal strength in dB - Sum of samples"
-+517, IPFIX_FT_WPROBE_SIGNAL_SS, 8, IPFIX_CODING_UINT, "link_signal_ss", "wprobe link signal strength in dB - Sum of squared samples"
-+518, IPFIX_FT_WPROBE_IEEE_RX_RATE_N, 4, IPFIX_CODING_UINT, "link_ieee_rx_rate_n", "wprobe link IEEE 802.11 RX data rate - Number of samples"
-+519, IPFIX_FT_WPROBE_IEEE_RX_RATE_S, 8, IPFIX_CODING_UINT, "link_ieee_rx_rate_s", "wprobe link IEEE 802.11 RX data rate - Sum of samples"
-+520, IPFIX_FT_WPROBE_IEEE_RX_RATE_SS, 8, IPFIX_CODING_UINT, "link_ieee_rx_rate_ss", "wprobe link IEEE 802.11 RX data rate - Sum of squared samples"
-+521, IPFIX_FT_WPROBE_IEEE_TX_RATE_N, 4, IPFIX_CODING_UINT, "link_ieee_tx_rate_n", "wprobe link IEEE 802.11 TX data rate - Number of samples"
-+522, IPFIX_FT_WPROBE_IEEE_TX_RATE_S, 8, IPFIX_CODING_UINT, "link_ieee_tx_rate_s", "wprobe link IEEE 802.11 TX data rate - Sum of samples"
-+523, IPFIX_FT_WPROBE_IEEE_TX_RATE_SS, 8, IPFIX_CODING_UINT, "link_ieee_tx_rate_ss", "wprobe link IEEE 802.11 TX data rate - Sum of squared samples"
-+524, IPFIX_FT_WPROBE_RETRANSMIT_200_N, 4, IPFIX_CODING_UINT, "link_retransmit_200_n", "wprobe link total retransmissions per packet - <200 bytes - Number of samples"
-+525, IPFIX_FT_WPROBE_RETRANSMIT_200_S, 8, IPFIX_CODING_UINT, "link_retransmit_200_s", "wprobe link total retransmissions per packet - <200 bytes - Sum of samples"
-+526, IPFIX_FT_WPROBE_RETRANSMIT_200_SS, 8, IPFIX_CODING_UINT, "link_retransmit_200_ss", "wprobe link total retransmissions per packet - <200 bytes - Sum of squared samples"
-+527, IPFIX_FT_WPROBE_RETRANSMIT_400_N, 4, IPFIX_CODING_UINT, "link_retransmit_400_n", "wprobe link total retransmissions per packet - <400 bytes - Number of samples"
-+528, IPFIX_FT_WPROBE_RETRANSMIT_400_S, 8, IPFIX_CODING_UINT, "link_retransmit_400_s", "wprobe link total retransmissions per packet - <400 bytes - Sum of samples"
-+529, IPFIX_FT_WPROBE_RETRANSMIT_400_SS, 8, IPFIX_CODING_UINT, "link_retransmit_400_ss", "wprobe link total retransmissions per packet - <400 bytes - Sum of squared samples"
-+530, IPFIX_FT_WPROBE_RETRANSMIT_800_N, 4, IPFIX_CODING_UINT, "link_retransmit_800_n", "wprobe link total retransmissions per packet - <800 bytes - Number of samples"
-+531, IPFIX_FT_WPROBE_RETRANSMIT_800_S, 8, IPFIX_CODING_UINT, "link_retransmit_800_s", "wprobe link total retransmissions per packet - <800 bytes - Sum of samples"
-+532, IPFIX_FT_WPROBE_RETRANSMIT_800_SS, 8, IPFIX_CODING_UINT, "link_retransmit_800_ss", "wprobe link total retransmissions per packet - <800 bytes - Sum of squared samples"
-+533, IPFIX_FT_WPROBE_RETRANSMIT_1600_N, 4, IPFIX_CODING_UINT, "link_retransmit_1600_n", "wprobe link total retransmissions per packet - >800 bytes - Number of samples"
-+534, IPFIX_FT_WPROBE_RETRANSMIT_1600_S, 8, IPFIX_CODING_UINT, "link_retransmit_1600_s", "wprobe link total retransmissions per packet - >800 bytes - Sum of samples"
-+535, IPFIX_FT_WPROBE_RETRANSMIT_1600_SS, 8, IPFIX_CODING_UINT, "link_retransmit_1600_ss", "wprobe link total retransmissions per packet - >800 bytes - Sum of squared samples"
-+536, IPFIX_FT_WPROBE_FRAMES, 4, IPFIX_CODING_UINT, "global_frames", "wprobe global number of 802.11 frames seen"
-+537, IPFIX_FT_WPROBE_PROBEREQ, 4, IPFIX_CODING_UINT, "global_probereq", "wprobe global number of 802.11 probe requests seen"
diff --git a/package/libipfix/patches/120-ipfixmisc.patch b/package/libipfix/patches/120-ipfixmisc.patch
deleted file mode 100644
index e3f5a05c65..0000000000
--- a/package/libipfix/patches/120-ipfixmisc.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-Index: libipfix.r51/lib/Makefile.in
-===================================================================
---- libipfix.r51.orig/lib/Makefile.in	2008-08-05 15:15:23.000000000 +0200
-+++ libipfix.r51/lib/Makefile.in	2012-06-05 19:26:34.061692890 +0200
-@@ -41,7 +41,7 @@
- INCLS = -I. -I..
- CFLAGS = $(CCOPT) $(INCLS) $(DEFS)
- 
--TARGETS = libmisc.a libipfix.a
-+TARGETS = libipfixmisc.a libipfix.a
- OBJS = ipfix.o ipfix_col.o ipfix_print.o \
-        ipfix_col_files.o ipfix_col_db.o @IPFIX_DB_OBJ@ @IPFIX_SSL_OBJ@
- DEPHDR = ipfix.h ipfix_def.h ipfix_fields.h ipfix_def_fokus.h ipfix_fields_fokus.h
-@@ -60,11 +60,11 @@
- install:
- 	@[ -d ${libdir} ] || (mkdir -p ${libdir}; chmod 755 ${libdir})
- 	$(INSTALL_DATA) libipfix.a ${libdir}/
--	$(INSTALL_DATA) libmisc.a ${libdir}/
-+	$(INSTALL_DATA) libipfixmisc.a ${libdir}/
- 	@[ -d ${includedir} ] || (mkdir -p ${includedir}; chmod 755 ${includedir})
- 	$(INSTALL_HEADER) ipfix*.h mlog.h mpoll.h ${includedir}/
- 
--libmisc.a: $(MISCOBJS) Makefile
-+libipfixmisc.a: $(MISCOBJS) Makefile
- 	@rm -f $@
- 	$(AR) rc $@ $(MISCOBJS) 
- 
diff --git a/package/madwifi/Config.in b/package/madwifi/Config.in
deleted file mode 100644
index 7b72eb854e..0000000000
--- a/package/madwifi/Config.in
+++ /dev/null
@@ -1,55 +0,0 @@
-menu "Configuration"
-	depends on PACKAGE_kmod-madwifi
-
-config MADWIFI_DEBUG
-	bool "Enable compilation of debugging features"
-	depends on DEVEL
-	default n
-
-config MADWIFI_COMPRESSION
-	bool "Enable Atheros Super A/G Compression"
-	depends !TARGET_ar71xx
-	default n
-	help
-	  Enables Atheros Super A/G Hardware Compression Engine.
-
-config MADWIFI_SINGLE_MODULE
-	bool "Combine driver and net80211 into a single module"
-	default y
-	help
-	  This option combines all driver and stack related code (except for HAL)
-	  into a single module, thus saving space and removing unnecessary kernel
-	  exports
-
-choice
-	prompt "Rate control algorithm selection"
-	default MADWIFI_RCA_MINSTREL
-	help
-	  This option controls how MadWifi chooses its bitrate.
-
-config MADWIFI_RCA_MINSTREL
-	bool "Use the Minstrel rate control algorithm"
-	help
-	  This code is takes a wandering minstrel approach. Wander around the
-	  different rates, singing wherever you can. And then, look at the
-	  performance, and make a choice. Note that the wandering minstrel will
-	  always wander in directions where he/she feels he/she will get paid
-	  the best for his/her work.
-
-config MADWIFI_RCA_SAMPLERATE
-	bool "Use the SampleRate rate control algorithm"
-	help
-	  SampleRate decides on the transmission bit-rate based on the past
-	  history of performance; it keeps a record of the number of successive
-	  failures, the number of successful transmits and the total transmission
-	  time along with the destination for that bit-rate. Stale samples are
-	  removed based on a EWMA windowing mechanism. If in the sampling
-	  process, no successful acknowledgment is received or the number of
-	  packets sent is multiple of 10 on a specific link, it transmits the
-	  packet with the highest rate which has not failed 4 successive times.
-	  Other than that it transmits packets at the rate which has the lowest
-	  average transmission time.
-
-endchoice
-
-endmenu
diff --git a/package/madwifi/Makefile b/package/madwifi/Makefile
deleted file mode 100644
index f915f56f9f..0000000000
--- a/package/madwifi/Makefile
+++ /dev/null
@@ -1,266 +0,0 @@
-#
-# Copyright (C) 2006-2009 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=madwifi
-
-PKG_REV:=3314
-PKG_VERSION:=r$(PKG_REV)
-PKG_RELEASE:=6
-
-PKG_SOURCE_PROTO:=svn
-PKG_SOURCE_VERSION:=$(PKG_REV)
-PKG_SOURCE_SUBDIR:=$(if $(PKG_BRANCH),$(PKG_BRANCH),madwifi-trunk)-$(PKG_VERSION)
-PKG_SOURCE_URL:=http://madwifi-project.org/svn/madwifi/$(if $(PKG_BRANCH),branches/$(PKG_BRANCH),trunk)
-PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
-PKG_MIRROR_MD5SUM:=086b026d1c1561be8a949b79b0931404
-
-PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(if $(PKG_BRANCH),$(PKG_BRANCH),madwifi-trunk)-$(PKG_VERSION)
-
-HAL_VERSION:=20090508
-HAL_FILE:=ath_hal-$(HAL_VERSION).tgz
-HAL_MD5SUM:=4ab7ae8bdb96c0be388c98bf8f92d5ca
-
-PKG_BUILD_DEPENDS:=wprobe
-
-include $(INCLUDE_DIR)/package.mk
-
-ifdef CONFIG_MADWIFI_COMPRESSION
-  COMPRESSION:=1
-else
-  COMPRESSION:=0
-endif
-
-define Download/hal
-  FILE:=$(HAL_FILE)
-  URL:=http://mirror2.openwrt.org/sources
-  MD5SUM:=$(HAL_MD5SUM)
-endef
-$(eval $(call Download,hal))
-
-
-ifneq ($(CONFIG_TARGET_atheros),)
-  BUS:=AHB
-else
-  ifneq ($(CONFIG_PCI_SUPPORT),)
-    BUS:=PCI
-  endif
-endif
-
-ifneq ($(CONFIG_CPU_MIPS32_R2),)
-  ifeq ($(ARCH),mips)
-    HAL_TARGET:=mips32r2-be-elf
-  endif
-  ifeq ($(ARCH),mipsel)
-    HAL_TARGET:=mips32r2-le-elf
-  endif
-else
-  ifeq ($(ARCH),mips)
-    HAL_TARGET:=mips32-be-elf
-  endif
-  ifeq ($(ARCH),mipsel)
-    HAL_TARGET:=mips32-le-elf
-  endif
-endif
-ifeq ($(ARCH),i386)
-  HAL_TARGET:=i386-elf
-endif
-ifeq ($(ARCH),i686)
-  HAL_TARGET:=i386-elf
-endif
-ifeq ($(ARCH),armeb)
-  HAL_TARGET:=xscale-be-elfgnueabi
-endif
-ifeq ($(ARCH),arm)
-  HAL_TARGET:=xscale-le-elfgnueabi
-  ifeq ($(BOARD),cns21xx)
-    HAL_TARGET:=armv4-le-elfgnueabi
-  endif
-  ifeq ($(BOARD),cns3xxx)
-    HAL_TARGET:=arm11-le-elfgnueabi
-  endif
-  ifeq ($(BOARD),gemini)
-    HAL_TARGET:=armv4-le-elfgnueabi
-  endif
-endif
-ifeq ($(ARCH),powerpc)
-  HAL_TARGET:=powerpc-be-elf
-endif
-ifneq ($(CONFIG_TARGET_atheros),)
-  HAL_TARGET:=wisoc
-endif
-
-ifdef CONFIG_MADWIFI_RCA_MINSTREL
-  RATE_CONTROL:=minstrel
-endif
-
-ifdef CONFIG_MADWIFI_RCA_ONOE
-  RATE_CONTROL:=onoe
-endif
-
-ifdef CONFIG_MADWIFI_RCA_AMRR
-  RATE_CONTROL:=amrr
-endif
-
-ifdef CONFIG_MADWIFI_RCA_SAMPLERATE
-  RATE_CONTROL:=sample
-endif
-
-ifneq ($(CONFIG_MADWIFI_SINGLE_MODULE),)
-MADWIFI_FILES:= $(PKG_BUILD_DIR)/ath_hal/ath_hal.ko
-else
-MADWIFI_FILES:= \
-	$(PKG_BUILD_DIR)/net80211/wlan.ko \
-	$(PKG_BUILD_DIR)/net80211/wlan_scan_ap.ko \
-	$(PKG_BUILD_DIR)/net80211/wlan_scan_sta.ko \
-	$(PKG_BUILD_DIR)/ath_hal/ath_hal.ko \
-	$(PKG_BUILD_DIR)/ath_rate/$(RATE_CONTROL)/ath_rate_$(RATE_CONTROL).ko \
-	$(PKG_BUILD_DIR)/net80211/wlan_acl.ko \
-	$(PKG_BUILD_DIR)/net80211/wlan_ccmp.ko \
-	$(PKG_BUILD_DIR)/net80211/wlan_tkip.ko \
-	$(PKG_BUILD_DIR)/net80211/wlan_wep.ko \
-	$(PKG_BUILD_DIR)/net80211/wlan_xauth.ko
-endif
-
-ifneq ($(CONFIG_MADWIFI_SINGLE_MODULE),)
-  MADWIFI_AUTOLOAD:= ath_hal
-else
-  MADWIFI_AUTOLOAD:= \
-	wlan \
-	wlan_scan_ap \
-	wlan_scan_sta \
-	ath_hal \
-	ath_rate_$(RATE_CONTROL) \
-	wlan_acl \
-	wlan_ccmp \
-	wlan_tkip \
-	wlan_wep \
-	wlan_xauth
-endif
-
-ifeq ($(findstring AHB,$(BUS)),AHB)
-  MADWIFI_FILES+= $(PKG_BUILD_DIR)/ath/ath_ahb.ko
-  MADWIFI_AUTOLOAD+= ath_ahb
-endif
-ifeq ($(findstring PCI,$(BUS)),PCI)
-  MADWIFI_FILES+= $(PKG_BUILD_DIR)/ath/ath_pci.ko
-  MADWIFI_AUTOLOAD+= ath_pci
-endif
-
-MADWIFI_APPLETS:=80211stats athchans athkey athstats wlanconfig ath_info madwifi_multi
-ifdef CONFIG_MADWIFI_DEBUG
-  MADWIFI_APPLETS += athdebug 80211debug
-endif
-
-define KernelPackage/madwifi
-  SUBMENU:=Wireless Drivers
-  TITLE:=Driver for Atheros wireless chipsets
-  URL:=http://madwifi-project.org/
-  DEPENDS:=+wireless-tools @PCI_SUPPORT @(!(TARGET_avr32||TARGET_cobalt||TARGET_ep93xx||TARGET_etrax||TARGET_octeon||TARGET_pxcab||TARGET_sibyte)||BROKEN) +@DRIVER_WEXT_SUPPORT
-  FILES:=$(MADWIFI_FILES)
-  AUTOLOAD:=$(call AutoLoad,50,$(MADWIFI_AUTOLOAD))
-  MENU:=1
-endef
-
-define KernelPackage/madwifi/description
- This package contains a driver for Atheros 802.11a/b/g chipsets.
-endef
-
-define KernelPackage/madwifi/config
-	source "$(SOURCE)/Config.in"
-endef
-
-MADWIFI_INC = \
-	-I$(PKG_BUILD_DIR) \
-	-I$(PKG_BUILD_DIR)/include \
-	-I$(PKG_BUILD_DIR)/hal \
-	-I$(PKG_BUILD_DIR)/ath \
-	-I$(PKG_BUILD_DIR)/ath_hal \
-	-I$(PKG_BUILD_DIR)/net80211 \
-	-I$(STAGING_DIR)/usr/include/wprobe \
-	-include $(PKG_BUILD_DIR)/include/compat.h
-
-MAKE_ARGS:= \
-	PATH="$(TARGET_PATH)" \
-	ARCH="$(LINUX_KARCH)" \
-	ARCH-y="$(LINUX_KARCH)" \
-	CROSS_COMPILE="$(TARGET_CROSS)" \
-	TARGET="$(HAL_TARGET)" \
-	TOOLPREFIX="$(KERNEL_CROSS)" \
-	TOOLPATH="$(KERNEL_CROSS)" \
-	KERNELPATH="$(LINUX_DIR)" \
-	LDOPTS="--no-warn-mismatch " \
-	ATH_RATE="$(RATE_CONTROL)" \
-	ATH_CAP_SUPERG_COMP="$(COMPRESSION)" \
-	DO_MULTI=1 \
-	SINGLE_MODULE=$(if $(CONFIG_MADWIFI_SINGLE_MODULE),1) \
-	INCS="$(MADWIFI_INC)" \
-	$(if $(CONFIG_MADWIFI_DEBUG),,DEBUG=) WARNINGS="-Wno-unused"
-
-MAKE_VARS:= \
-	COPTS="-DATH_REVERSE_ENGINEERING=1" \
-
-define Build/Prepare/HAL
-	rm -rf $(PKG_BUILD_DIR)/tmp
-	mkdir -p $(PKG_BUILD_DIR)/tmp
-	tar xvzf $(DL_DIR)/$(HAL_FILE) -C $(PKG_BUILD_DIR)/tmp
-	$(CP) $(PKG_BUILD_DIR)/tmp/ath_hal*/* $(PKG_BUILD_DIR)/hal/
-	rm -rf $(PKG_BUILD_DIR)/tmp
-endef
-
-define Build/Prepare
-	$(call Build/Prepare/Default)
-	$(call Build/Prepare/HAL)
-	# patch cflags
-	$(SED) 's, -E[LB],,' \
-		-e 's, -mips2,,' \
-		-e 's, -mapcs-32,,' \
-		-e 's, -mlong-calls,,' \
-		$(PKG_BUILD_DIR)/hal/public/*.inc
-	$(SED) 's,march=armv4,march=armv5te,' \
-		$(PKG_BUILD_DIR)/hal/public/xscale*.inc
-endef
-
-ifeq ($(findstring AHB,$(BUS)),AHB)
-  define Build/Compile/ahb
-	$(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_ARGS) BUS="AHB" modules
-	$(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_ARGS) CFLAGS="$(TARGET_CFLAGS)" tools
-  endef
-endif
-
-ifeq ($(findstring PCI,$(BUS)),PCI)
-  define Build/Compile/pci
-	$(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_ARGS) BUS="PCI" modules
-	$(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_ARGS) CFLAGS="$(TARGET_CFLAGS)" tools
-  endef
-endif
-
-define Build/Configure
-	$(SED) 's,-E[LB] ,,g' $(PKG_BUILD_DIR)/hal/public/*.inc
-endef
-
-define Build/Compile
-	$(call Build/Compile/ahb)
-	$(call Build/Compile/pci)
-endef
-
-define Build/InstallDev
-	mkdir -p $(1)/usr/include/madwifi
-	$(CP) $(PKG_BUILD_DIR)/include $(1)/usr/include/madwifi/
-	mkdir -p $(1)/usr/include/madwifi/net80211
-	$(CP) $(PKG_BUILD_DIR)/net80211/*.h $(1)/usr/include/madwifi/net80211/
-endef
-
-define KernelPackage/madwifi/install
-	$(INSTALL_DIR) $(1)/usr/sbin
-	$(CP) ./files/* $(1)/
-	$(CP) $(foreach applet,$(MADWIFI_APPLETS),$(PKG_BUILD_DIR)/tools/$(applet)) $(1)/usr/sbin/
-endef
-
-$(eval $(call KernelPackage,madwifi))
diff --git a/package/madwifi/files/etc/hotplug.d/net/10-madwifi b/package/madwifi/files/etc/hotplug.d/net/10-madwifi
deleted file mode 100644
index f5afce3f21..0000000000
--- a/package/madwifi/files/etc/hotplug.d/net/10-madwifi
+++ /dev/null
@@ -1,12 +0,0 @@
-if [ "$ACTION" = "add" -o "$ACTION" = "register" ]; then
-	case "$INTERFACE" in
-		ath*.sta*)
-			local BASEIF="${INTERFACE%%\.*}"
-
-			include /lib/network
-			scan_interfaces
-			local CONFIG="$(find_config "$BASEIF")" 
-			[ -n "$CONFIG" ] && setup_interface "$INTERFACE" "$CONFIG"
-		;;
-	esac
-fi
diff --git a/package/madwifi/files/lib/wifi/madwifi.sh b/package/madwifi/files/lib/wifi/madwifi.sh
deleted file mode 100755
index 2e37325511..0000000000
--- a/package/madwifi/files/lib/wifi/madwifi.sh
+++ /dev/null
@@ -1,498 +0,0 @@
-#!/bin/sh
-append DRIVERS "atheros"
-
-find_atheros_phy() {
-	local device="$1"
-
-	local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
-	config_get phy "$device" phy
-	[ -z "$phy" -a -n "$macaddr" ] && {
-		cd /proc/sys/dev
-		for phy in $(ls -d wifi* 2>&-); do
-			[ "$macaddr" = "$(cat /sys/class/net/${phy}/address)" ] || continue
-			config_set "$device" phy "$phy"
-			break
-		done
-		config_get phy "$device" phy
-	}
-	[ -n "$phy" -a -d "/proc/sys/dev/$phy" ] || {
-		echo "phy for wifi device $1 not found"
-		return 1
-	}
-	[ -z "$macaddr" ] && {
-		config_set "$device" macaddr "$(cat /sys/class/net/${phy}/address)"
-	}
-	return 0
-}
-
-scan_atheros() {
-	local device="$1"
-	local wds
-	local adhoc ahdemo sta ap monitor disabled
-
-	[ ${device%[0-9]} = "wifi" ] && config_set "$device" phy "$device"
-
-	local ifidx=0
-	
-	config_get vifs "$device" vifs
-	for vif in $vifs; do
-		config_get_bool disabled "$vif" disabled 0
-		[ $disabled = 0 ] || continue
-
-		local vifname
-		[ $ifidx -gt 0 ] && vifname="ath${device#radio}-$ifidx" || vifname="ath${device#radio}"
-
-		config_get ifname "$vif" ifname
-		config_set "$vif" ifname "${ifname:-$vifname}"
-		
-		config_get mode "$vif" mode
-		case "$mode" in
-			adhoc|ahdemo|sta|ap|monitor)
-				append $mode "$vif"
-			;;
-			wds)
-				config_get ssid "$vif" ssid
-				[ -z "$ssid" ] && continue
-
-				config_set "$vif" wds 1
-				config_set "$vif" mode sta
-				mode="sta"
-				addr="$ssid"
-				${addr:+append $mode "$vif"}
-			;;
-			*) echo "$device($vif): Invalid mode, ignored."; continue;;
-		esac
-
-		ifidx=$(($ifidx + 1))
-	done
-
-	case "${adhoc:+1}:${sta:+1}:${ap:+1}" in
-		# valid mode combinations
-		1::) wds="";;
-		1::1);;
-		:1:1)config_set "$device" nosbeacon 1;; # AP+STA, can't use beacon timers for STA
-		:1:);;
-		::1);;
-		::);;
-		*) echo "$device: Invalid mode combination in config"; return 1;;
-	esac
-
-	config_set "$device" vifs "${sta:+$sta }${ap:+$ap }${adhoc:+$adhoc }${ahdemo:+$ahdemo }${wds:+$wds }${monitor:+$monitor}"
-}
-
-
-disable_atheros() (
-	local device="$1"
-
-	find_atheros_phy "$device" || return 0
-	config_get phy "$device" phy
-
-	set_wifi_down "$device"
-
-	include /lib/network
-	cd /proc/sys/net
-	for dev in *; do
-		grep "$phy" "$dev/%parent" >/dev/null 2>/dev/null && {
-			[ -f "/var/run/wifi-${dev}.pid" ] &&
-				kill "$(cat "/var/run/wifi-${dev}.pid")"
-			ifconfig "$dev" down
-			unbridge "$dev"
-			wlanconfig "$dev" destroy
-		}
-	done
-	return 0
-)
-
-enable_atheros() {
-	local device="$1"
-
-	find_atheros_phy "$device" || return 0
-	config_get phy "$device" phy
-
-	config_get regdomain "$device" regdomain
-	[ -n "$regdomain" ] && echo "$regdomain" > /proc/sys/dev/$phy/regdomain
-
-	config_get country "$device" country
-	case "$country" in
-		[A-Za-z]*) country=`grep -i "$country" /lib/wifi/madwifi_countrycodes.txt |cut -d " " -f 2`;;
-		[0-9]*) ;;
-		*) country="" ;;
-	esac
-	[ -n "$country" ] && echo "$country" > /proc/sys/dev/$phy/countrycode
-
-	config_get_bool outdoor "$device" outdoor "0"
-	echo "$outdoor" > /proc/sys/dev/$phy/outdoor
-
-	config_get channel "$device" channel
-	config_get vifs "$device" vifs
-	config_get txpower "$device" txpower
-
-	[ auto = "$channel" ] && channel=0
-
-	config_get_bool antdiv "$device" diversity
-	config_get antrx "$device" rxantenna
-	config_get anttx "$device" txantenna
-	config_get_bool softled "$device" softled
-	config_get antenna "$device" antenna
-
-	devname="$(cat /proc/sys/dev/$phy/dev_name)"
-	local antgpio=
-	local invert=
-	case "$devname" in
-		NanoStation2) antgpio=7; invert=1;;
-		NanoStation5) antgpio=1; invert=1;;
-		"NanoStation Loco2") antgpio=2;;
-		"NanoStation Loco5")
-			case "$antenna" in
-				horizontal) antdiv=0; anttx=1; antrx=1;;
-				vertical) antdiv=0; anttx=2; antrx=2;;
-				*) antdiv=1; anttx=0; antrx=0;;
-			esac
-		;;
-	esac
-	if [ -n "$invert" ]; then
-		_set="clear"
-		_clear="set"
-	else
-		_set="set"
-		_clear="clear"
-	fi
-	if [ -n "$antgpio" ]; then
-		softled=0
-		case "$devname" in
-			"NanoStation Loco2")
-				antdiv=0
-				antrx=1
-				anttx=1
-				case "$antenna" in
-					horizontal) gpioval=0;;
-					*) gpioval=1;;
-				esac
-			;;
-			*)
-				case "$antenna" in
-					external) antdiv=0; antrx=1; anttx=1; gpioval=1;;
-					horizontal) antdiv=0; antrx=1; anttx=1; gpioval=0;;
-					vertical) antdiv=0; antrx=2; anttx=2; gpioval=0;;
-					auto) antdiv=1; antrx=0; anttx=0; gpioval=0;;
-				esac
-			;;
-		esac
-
-		[ -x "$(which gpioctl 2>/dev/null)" ] || antenna=
-		gpioctl "dirout" "$antgpio" >/dev/null 2>&1
-		case "$gpioval" in
-			0)
-				gpioctl "$_clear" "$antgpio" >/dev/null 2>&1
-			;;
-			1)
-				gpioctl "$_set" "$antgpio" >/dev/null 2>&1
-			;;
-		esac
-	fi
-
-	[ -n "$antdiv" ] && sysctl -w dev."$phy".diversity="$antdiv" >&-
-	[ -n "$antrx" ] && sysctl -w dev."$phy".rxantenna="$antrx" >&-
-	[ -n "$anttx" ] && sysctl -w dev."$phy".txantenna="$anttx" >&-
-	[ -n "$softled" ] && sysctl -w dev."$phy".softled="$softled" >&-
-
-	config_get distance "$device" distance
-	[ -n "$distance" ] && sysctl -w dev."$phy".distance="$distance" >&-
-
-	for vif in $vifs; do
-		local start_hostapd= vif_txpower= nosbeacon=
-		config_get ifname "$vif" ifname
-		config_get enc "$vif" encryption
-		config_get eap_type "$vif" eap_type
-		config_get mode "$vif" mode
-
-		case "$mode" in
-			sta) config_get_bool nosbeacon "$device" nosbeacon;;
-			adhoc) config_get_bool nosbeacon "$vif" sw_merge 1;;
-		esac
-
-		[ "$nosbeacon" = 1 ] || nosbeacon=""
-		ifname=$(wlanconfig "$ifname" create nounit wlandev "$phy" wlanmode "$mode" ${nosbeacon:+nosbeacon})
-		[ $? -ne 0 ] && {
-			echo "enable_atheros($device): Failed to set up $mode vif $ifname" >&2
-			continue
-		}
-		config_set "$vif" ifname "$ifname"
-
-		config_get hwmode "$device" hwmode
-		[ -z "$hwmode" ] && config_get hwmode "$device" mode
-
-		pureg=0
-		case "$hwmode" in
-			*b) hwmode=11b;;
-			*bg) hwmode=11g;;
-			*g) hwmode=11g; pureg=1;;
-			*gdt) hwmode=11gdt;;
-			*a) hwmode=11a;;
-			*adt) hwmode=11adt;;
-			*ast) hwmode=11ast;;
-			*fh) hwmode=fh;;
-			*) hwmode=auto;;
-		esac
-		iwpriv "$ifname" mode "$hwmode"
-		iwpriv "$ifname" pureg "$pureg"
-
-		iwconfig "$ifname" channel "$channel" >/dev/null 2>/dev/null 
-
-		config_get_bool hidden "$vif" hidden 0
-		iwpriv "$ifname" hide_ssid "$hidden"
-
-		config_get ff "$vif" ff
-		if [ -n "$ff" ]; then
-			iwpriv "$ifname" ff "$ff"
-		fi
-
-		config_get wds "$vif" wds
-		case "$wds" in
-			1|on|enabled) wds=1;;
-			*) wds=0;;
-		esac
-		iwpriv "$ifname" wds "$wds" >/dev/null 2>&1
-
-		[ "$mode" = ap -a "$wds" = 1 ] && {
-			config_get_bool wdssep "$vif" wdssep 1
-			[ -n "$wdssep" ] && iwpriv "$ifname" wdssep "$wdssep"
-		}
-
-		case "$enc" in
-			wep*)
-				case "$enc" in
-					*shared*) iwpriv "$ifname" authmode 2;;
-					*)        iwpriv "$ifname" authmode 1;;
-				esac
-				for idx in 1 2 3 4; do
-					config_get key "$vif" "key${idx}"
-					iwconfig "$ifname" enc "[$idx]" "${key:-off}"
-				done
-				config_get key "$vif" key
-				key="${key:-1}"
-				case "$key" in
-					[1234]) iwconfig "$ifname" enc "[$key]";;
-					*) iwconfig "$ifname" enc "$key";;
-				esac
-			;;
-			psk*|wpa*)
-				start_hostapd=1
-				config_get key "$vif" key
-			;;
-		esac
-
-		case "$mode" in
-			sta|adhoc|ahdemo)
-				config_get addr "$vif" bssid
-				[ -z "$addr" ] || { 
-					iwconfig "$ifname" ap "$addr"
-				}
-			;;
-		esac
-
-		config_get_bool uapsd "$vif" uapsd 0
-		iwpriv "$ifname" uapsd "$uapsd"
-
-		config_get_bool bgscan "$vif" bgscan
-		[ -n "$bgscan" ] && iwpriv "$ifname" bgscan "$bgscan"
-
-		config_get rate "$vif" rate
-		[ -n "$rate" ] && iwconfig "$ifname" rate "${rate%%.*}"
-
-		config_get mcast_rate "$vif" mcast_rate
-		[ -n "$mcast_rate" ] && iwpriv "$ifname" mcast_rate "${mcast_rate%%.*}"
-
-		config_get frag "$vif" frag
-		[ -n "$frag" ] && iwconfig "$ifname" frag "${frag%%.*}"
-
-		config_get rts "$vif" rts
-		[ -n "$rts" ] && iwconfig "$ifname" rts "${rts%%.*}"
-
-		config_get_bool comp "$vif" compression 0
-		iwpriv "$ifname" compression "$comp" >/dev/null 2>&1
-
-		config_get minrate "$vif" minrate
-		[ -n "$minrate" ] && iwpriv "$ifname" minrate "$minrate"
-
-		config_get maxrate "$vif" maxrate
-		[ -n "$maxrate" ] && iwpriv "$ifname" maxrate "$maxrate"
-
-		config_get_bool burst "$vif" bursting
-		[ -n "$burst" ] && iwpriv "$ifname" burst "$burst"
-
-		config_get_bool wmm "$vif" wmm
-		[ -n "$wmm" ] && iwpriv "$ifname" wmm "$wmm"
-
-		config_get_bool xr "$vif" xr
-		[ -n "$xr" ] && iwpriv "$ifname" xr "$xr"
-
-		config_get_bool ar "$vif" ar
-		[ -n "$ar" ] && iwpriv "$ifname" ar "$ar"
-
-		config_get_bool beacon_power "$vif" beacon_power
-		[ -n "$beacon_power" ] && iwpriv "$ifname" beacon_pwr "$beacon_power"
-
-		config_get_bool doth "$vif" doth 0
-		[ -n "$doth" ] && iwpriv "$ifname" doth "$doth"
-
-		config_get_bool probereq "$vif" probereq
-		[ -n "$probereq" ] && iwpriv "$ifname" probereq "$probereq"
-
-		config_get maclist "$vif" maclist
-		[ -n "$maclist" ] && {
-			# flush MAC list
-			iwpriv "$ifname" maccmd 3
-			for mac in $maclist; do
-				iwpriv "$ifname" addmac "$mac"
-			done
-		}
-
-		config_get macpolicy "$vif" macpolicy
-		case "$macpolicy" in
-			allow)
-				iwpriv "$ifname" maccmd 1
-			;;
-			deny)
-				iwpriv "$ifname" maccmd 2
-			;;
-			*)
-				# default deny policy if mac list exists
-				[ -n "$maclist" ] && iwpriv "$ifname" maccmd 2
-			;;
-		esac
-
-		ifconfig "$ifname" up
-
-		local net_cfg bridge
-		net_cfg="$(find_net_config "$vif")"
-		[ -z "$net_cfg" ] || {
-			bridge="$(bridge_interface "$net_cfg")"
-			config_set "$vif" bridge "$bridge"
-			start_net "$ifname" "$net_cfg"
-		}
-
-		config_get ssid "$vif" ssid
-		[ -n "$ssid" ] && {
-			iwconfig "$ifname" essid on
-			iwconfig "$ifname" essid ${ssid:+-- }"$ssid"
-		}
-
-		set_wifi_up "$vif" "$ifname"
-
-		# TXPower settings only work if device is up already
-		# while atheros hardware theoretically is capable of per-vif (even per-packet) txpower
-		# adjustment it does not work with the current atheros hal/madwifi driver
-
-		config_get vif_txpower "$vif" txpower
-		# use vif_txpower (from wifi-iface) instead of txpower (from wifi-device) if
-		# the latter doesn't exist
-		txpower="${txpower:-$vif_txpower}"
-		[ -z "$txpower" ] || iwconfig "$ifname" txpower "${txpower%%.*}"
-
-		case "$mode" in
-			ap)
-				config_get_bool isolate "$vif" isolate 0
-				iwpriv "$ifname" ap_bridge "$((isolate^1))"
-
-				if [ -n "$start_hostapd" ] && eval "type hostapd_setup_vif" 2>/dev/null >/dev/null; then
-					hostapd_setup_vif "$vif" madwifi || {
-						echo "enable_atheros($device): Failed to set up hostapd for interface $ifname" >&2
-						# make sure this wifi interface won't accidentally stay open without encryption
-						ifconfig "$ifname" down
-						wlanconfig "$ifname" destroy
-						continue
-					}
-				fi
-			;;
-			wds|sta)
-				if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
-					wpa_supplicant_setup_vif "$vif" wext || {
-						echo "enable_atheros($device): Failed to set up wpa_supplicant for interface $ifname" >&2
-						ifconfig "$ifname" down
-						wlanconfig "$ifname" destroy
-						continue
-					}
-				fi
-			;;
-			adhoc)
-				if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
-					wpa_supplicant_setup_vif "$vif" madwifi || {
-						echo "enable_atheros($device): Failed to set up wpa"
-						ifconfig "$ifname" down
-						wlanconfig "$ifname" destroy
-						continue
-					}
-				fi
-		esac
-	done
-}
-
-check_atheros_device() {
-	[ ${1%[0-9]} = "wifi" ] && config_set "$1" phy "$1"
-	config_get phy "$1" phy
-	[ -z "$phy" ] && {
-		find_atheros_phy "$1" >/dev/null || return 0
-		config_get phy "$1" phy
-	}
-	[ "$phy" = "$dev" ] && found=1
-}
-
-
-detect_atheros() {
-	devidx=0
-	config_load wireless
-	while :; do
-		config_get type "radio$devidx" type
-		[ -n "$type" ] || break
-		devidx=$(($devidx + 1))
-	done
-	cd /proc/sys/dev
-	[ -d ath ] || return
-	for dev in $(ls -d wifi* 2>&-); do
-		found=0
-		config_foreach check_atheros_device wifi-device
-		[ "$found" -gt 0 ] && continue
-
-		devname="$(cat /proc/sys/dev/$dev/dev_name)"
-		case "$devname" in
-			"NanoStation Loco2")
-				EXTRA_DEV="
-# Ubiquiti NanoStation Loco2 features
-	option antenna	vertical # (horizontal|vertical)
-"
-			;;
-			"NanoStation Loco5")
-				EXTRA_DEV="
-# Ubiquiti NanoStation Loco5 features
-	option antenna	auto # (auto|horizontal|vertical)
-"
-			;;
-			NanoStation*)
-				EXTRA_DEV="
-# Ubiquiti NanoStation features
-	option antenna	auto # (auto|horizontal|vertical|external)
-"
-			;;
-		esac
-
-		cat <<EOF
-config wifi-device  radio$devidx
-	option type     atheros
-	option channel  auto
-	option macaddr	$(cat /sys/class/net/${dev}/address)
-$EXTRA_DEV
-	# REMOVE THIS LINE TO ENABLE WIFI:
-	option disabled 1
-
-config wifi-iface
-	option device	radio$devidx
-	option network	lan
-	option mode	ap
-	option ssid	OpenWrt
-	option encryption none
-
-EOF
-	devidx=$(($devidx + 1))
-	done
-}
diff --git a/package/madwifi/files/lib/wifi/madwifi_countrycodes.txt b/package/madwifi/files/lib/wifi/madwifi_countrycodes.txt
deleted file mode 100644
index 624048bdc0..0000000000
--- a/package/madwifi/files/lib/wifi/madwifi_countrycodes.txt
+++ /dev/null
@@ -1,239 +0,0 @@
-AF 4
-AL 8
-DZ 12
-AS 16
-AD 20
-AO 24
-AI 660
-AQ 10
-AG 28
-AR 32
-AM 51
-AW 533
-AU 36
-AT 40
-AZ 31
-BS 44
-BH 48
-BD 50
-BB 52
-BY 112
-BE 56
-BZ 84
-BJ 204
-BM 60
-BT 64
-BO 68
-BA 70
-BW 72
-BV 74
-BR 76
-IO 86
-VG 92
-BN 96
-BG 100
-BF 854
-BI 108
-KH 116
-CM 120
-CA 124
-CV 132
-KY 136
-CF 140
-TD 148
-CL 152
-CN 156
-CX 162
-CC 166
-CO 170
-KM 174
-CD 180
-CG 178
-CK 184
-CR 188
-CI 384
-CU 192
-CY 196
-CZ 203
-DK 208
-DJ 262
-DM 212
-DO 214
-EC 218
-EG 818
-SV 222
-GQ 226
-ER 232
-EE 233
-ET 231
-FO 234
-FK 238
-FJ 242
-FI 246
-FR 250
-GF 254
-PF 258
-TF 260
-GA 266
-GM 270
-GE 268
-DE 276
-GH 288
-GI 292
-GR 300
-GL 304
-GD 308
-GP 312
-GU 316
-GT 320
-GN 324
-GW 624
-GY 328
-HT 332
-HM 334
-VA 336
-HN 340
-HK 344
-HR 191
-HU 348
-IS 352
-IN 356
-ID 360
-IR 364
-IQ 368
-IE 372
-IL 376
-IT 380
-JM 388
-JP 392
-JO 400
-KZ 398
-KE 404
-KI 296
-KP 408
-KR 410
-KW 414
-KG 417
-LA 418
-LV 428
-LB 422
-LS 426
-LR 430
-LY 434
-LI 438
-LT 440
-LU 442
-MO 446
-MK 807
-MG 450
-MW 454
-MY 458
-MV 462
-ML 466
-MT 470
-MH 584
-MQ 474
-MR 478
-MU 480
-YT 175
-MX 484
-FM 583
-MD 498
-MC 492
-MN 496
-MS 500
-MA 504
-MZ 508
-MM 104
-NA 516
-NR 520
-NP 524
-AN 530
-NL 528
-NC 540
-NZ 554
-NI 558
-NE 562
-NG 566
-NU 570
-NF 574
-MP 580
-NO 578
-OM 512
-PK 586
-PW 585
-PS 275
-PA 591
-PG 598
-PY 600
-PE 604
-PH 608
-PN 612
-PL 616
-PT 620
-PR 630
-QA 634
-RE 638
-RO 642
-RU 643
-RW 646
-SH 654
-KN 659
-LC 662
-PM 666
-VC 670
-WS 882
-SM 674
-ST 678
-SA 682
-SN 686
-CS 891
-SC 690
-SL 694
-SG 702
-SK 703
-SI 705
-SB 90
-SO 706
-ZA 710
-GS 239
-ES 724
-LK 144
-SD 736
-SR 740
-SJ 744
-SZ 748
-SE 752
-CH 756
-SY 760
-TW 158
-TJ 762
-TZ 834
-TH 764
-TL 626
-TG 768
-TK 772
-TO 776
-TT 780
-TN 788
-TR 792
-TM 795
-TC 796
-TV 798
-VI 850
-UG 800
-UA 804
-AE 784
-GB 826
-UM 581
-US 840
-UY 858
-UZ 860
-VU 548
-VE 862
-VN 704
-WF 876
-EH 732
-YE 887
-ZM 894
-ZW 716
diff --git a/package/madwifi/patches/102-multicall_binary.patch b/package/madwifi/patches/102-multicall_binary.patch
deleted file mode 100644
index 887a462e9f..0000000000
--- a/package/madwifi/patches/102-multicall_binary.patch
+++ /dev/null
@@ -1,315 +0,0 @@
---- a/tools/80211debug.c
-+++ b/tools/80211debug.c
-@@ -48,6 +48,7 @@
- #include <ctype.h>
- #include <getopt.h>
- #include <err.h>
-+#include "do_multi.h"
- 
- #undef ARRAY_SIZE
- #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-@@ -185,7 +186,7 @@ sysctlbyname(const char *oid0, void *old
- #endif /* __linux__ */
- 
- int
--main(int argc, char *argv[])
-+CMD(a80211debug)(int argc, char *argv[])
- {
- 	const char *ifname = "ath0";
- 	const char *cp, *tp;
---- a/tools/80211stats.c
-+++ b/tools/80211stats.c
-@@ -59,6 +59,7 @@
- #include "net80211/ieee80211.h"
- #include "net80211/ieee80211_crypto.h"
- #include "net80211/ieee80211_ioctl.h"
-+#include "do_multi.h"
- 
- #ifndef SIOCG80211STATS
- #define	SIOCG80211STATS	(SIOCDEVPRIVATE + 2)
-@@ -240,7 +241,7 @@ print_sta_stats(FILE *fd, const u_int8_t
- }
- 
- int
--main(int argc, char *argv[])
-+CMD(a80211stats)(int argc, char *argv[])
- {
- 	int c, len;
- 	struct ieee80211req_sta_info *si;
---- a/tools/athchans.c
-+++ b/tools/athchans.c
-@@ -58,6 +58,7 @@
- #include "net80211/ieee80211.h"
- #include "net80211/ieee80211_crypto.h"
- #include "net80211/ieee80211_ioctl.h"
-+#include "do_multi.h"
- 
- static	int s = -1;
- static const char *progname;
-@@ -140,8 +141,9 @@ usage(void)
- }
- 
- #define	MAXCHAN	((int)(sizeof(struct ieee80211req_chanlist) * NBBY))
-+
- int
--main(int argc, char *argv[])
-+CMD(athchans)(int argc, char *argv[])
- {
- 	const char *ifname = "wifi0";
- 	struct ieee80211req_chanlist chanlist;
---- a/tools/athctrl.c
-+++ b/tools/athctrl.c
-@@ -52,6 +52,7 @@
- #include <err.h>
- 
- #include <net/if.h>
-+#include "do_multi.h"
- 
- static int
- setsysctrl(const char *dev, const char *control , u_long value)
-@@ -88,7 +89,7 @@ static void usage(void)
- }
- 
- int
--main(int argc, char *argv[])
-+CMD(athctrl)(int argc, char *argv[])
- {
- 	char device[IFNAMSIZ + 1];
- 	int distance = -1;
---- a/tools/athdebug.c
-+++ b/tools/athdebug.c
-@@ -51,6 +51,7 @@
- #include <ctype.h>
- #include <getopt.h>
- #include <err.h>
-+#include "do_multi.h"
- 
- #undef ARRAY_SIZE
- #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-@@ -194,7 +195,7 @@ sysctlbyname(const char *oid0, void *old
- #endif /* __linux__ */
- 
- int
--main(int argc, char *argv[])
-+CMD(athdebug)(int argc, char *argv[])
- {
- #ifdef __linux__
- 	const char *ifname = "wifi0";
---- a/tools/athkey.c
-+++ b/tools/athkey.c
-@@ -58,6 +58,7 @@
- #include "net80211/ieee80211.h"
- #include "net80211/ieee80211_crypto.h"
- #include "net80211/ieee80211_ioctl.h"
-+#include "do_multi.h"
- 
- static int s = -1;
- static const char *progname;
-@@ -213,8 +214,7 @@ usage(void)
- 	exit(-1);
- }
- 
--int
--main(int argc, char *argv[])
-+int CMD(athkey)(int argc, char *argv[])
- {
- 	const char *ifname = "wifi0";
- 	struct ieee80211req_key setkey;
---- a/tools/athstats.c
-+++ b/tools/athstats.c
-@@ -65,6 +65,7 @@
- 
- #undef ARRAY_SIZE
- #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-+#include "do_multi.h"
- 
- static const struct {
- 	u_int		phyerr;
-@@ -228,7 +229,7 @@ catchalarm(int signo)
- }
- 
- int
--main(int argc, char *argv[])
-+CMD(athstats)(int argc, char *argv[])
- {
- #ifdef __linux__
- 	const char *ifname = "wifi0";
---- /dev/null
-+++ b/tools/do_multi.c
-@@ -0,0 +1,33 @@
-+#include <string.h>
-+#include <libgen.h>
-+#include "do_multi.h"
-+
-+int
-+main(int argc, char *argv[])
-+{
-+    char *progname;
-+    int ret = 0;
-+
-+    progname = basename(argv[0]);
-+
-+    if(strcmp(progname, "80211debug") == 0)
-+	ret = a80211debug_init(argc, argv);
-+    if(strcmp(progname, "80211stats") == 0)
-+	ret = a80211stats_init(argc, argv);
-+    if(strcmp(progname, "athchans") == 0)
-+	ret = athchans_init(argc, argv);
-+    if(strcmp(progname, "athctrl") == 0)
-+	ret =  athctrl_init(argc, argv);
-+    if(strcmp(progname, "athdebug") == 0)
-+	ret =  athdebug_init(argc, argv);
-+    if(strcmp(progname, "athkey") == 0)
-+	ret =  athkey_init(argc, argv);
-+    if(strcmp(progname, "athstats") == 0)
-+	ret =  athstats_init(argc, argv);
-+    if(strcmp(progname, "wlanconfig") == 0)
-+	ret =  wlanconfig_init(argc, argv);
-+    if(strcmp(progname, "ath_info") == 0)
-+	ret =  athinfo_init(argc, argv);
-+
-+    return ret;
-+}
---- /dev/null
-+++ b/tools/do_multi.h
-@@ -0,0 +1,15 @@
-+#ifdef DO_MULTI
-+int a80211debug_init(int argc, char *argv[]);
-+int a80211stats_init(int argc, char *argv[]);
-+int athchans_init(int argc, char *argv[]);
-+int athctrl_init(int argc, char *argv[]);
-+int athdebug_init(int argc, char *argv[]);
-+int athkey_init(int argc, char *argv[]);
-+int athstats_init(int argc, char *argv[]);
-+int wlanconfig_init(int argc, char *argv[]);
-+int athinfo_init(int argc, char *argv[]);
-+
-+#define CMD(name) name##_init
-+#else
-+#define CMD(name) main
-+#endif
---- a/tools/Makefile
-+++ b/tools/Makefile
-@@ -46,56 +46,55 @@ ifeq ($(HAL),)
- HAL=   $(TOP)/hal
- endif
- 
-+all: compile
- 
--ALL=	athstats 80211stats athkey athchans athctrl \
-+ALLPROGS=	athstats 80211stats athkey athchans athctrl \
- 	athdebug 80211debug wlanconfig ath_info
- 
--all:	$(ALL)
-+OBJS=	$(patsubst %,%.o,$(ALLPROGS))
- 
--INCS=	-I. -I$(HAL) -I$(TOP) -I$(ATH_HAL)
-+INCS=	-I. -I../ath -I$(HAL) -I$(TOP) -I$(ATH_HAL)
- CFLAGS=	-g -O2 -Wall
- ALL_CFLAGS= $(CFLAGS) $(INCS)
- LDFLAGS=
- 
--all:	$(ALL)
- 
--athstats: athstats.c
--	$(CC) -o athstats $(ALL_CFLAGS) -I$(TOP)/ath $(LDFLAGS) athstats.c
--80211stats: 80211stats.c
--	$(CC) -o 80211stats $(ALL_CFLAGS) $(LDFLAGS) 80211stats.c
--athkey: athkey.c
--	$(CC) -o athkey $(ALL_CFLAGS) $(LDFLAGS) athkey.c
--athchans: athchans.c
--	$(CC) -o athchans $(ALL_CFLAGS) $(LDFLAGS) athchans.c
--athctrl: athctrl.c
--	$(CC) -o athctrl $(ALL_CFLAGS) $(LDFLAGS) athctrl.c
--athdebug: athdebug.c
--	$(CC) -o athdebug $(ALL_CFLAGS) $(LDFLAGS) athdebug.c
--wlanconfig: wlanconfig.c
--	$(CC) -o wlanconfig $(ALL_CFLAGS) $(LDFLAGS) wlanconfig.c
--80211debug: 80211debug.c
--	$(CC) -o 80211debug $(ALL_CFLAGS) $(LDFLAGS) 80211debug.c
--ath_info: ath_info.c
--	$(CC) -o ath_info $(CFLAGS) ath_info.c
-+ifneq ($(DO_MULTI),)
-+ALL_CFLAGS += -DDO_MULTI=1
-+%.o: %.c
-+	${CC} $(ALL_CFLAGS) -c -o $@  $<
-+
-+madwifi_multi: $(OBJS) do_multi.o
-+	$(CC) -o $@ $^
-+
-+compile: madwifi_multi
-+	for i in $(ALLPROGS); do \
-+		ln -s -f madwifi_multi $$i; \
-+	done
-+else
-+$(ALLPROGS):
-+	$(CC) $(ALL_CFLAGS) -o $@ $@.c
-+
-+compile: $(ALLPROGS)
-+endif
- 
- 
- install: $(ALL) 
- 	install -d $(DESTDIR)$(BINDIR)
--	for i in $(ALL); do \
-+	for i in $(ALLPROGS) $(if $(DO_MULTI),madwifi_multi); do \
- 		install $$i $(DESTDIR)$(BINDIR)/$$i; \
--		$(STRIP) $(DESTDIR)$(BINDIR)/$$i; \
- 	done
- 	install -d $(DESTDIR)$(MANDIR)/man8
- 	install -m 0644 man/*.8 $(DESTDIR)$(MANDIR)/man8
- 	install $(TOP)/scripts/madwifi-unload $(DESTDIR)$(BINDIR)/madwifi-unload
- 
- uninstall:
--	for i in $(ALL); do \
-+	for i in $(ALLPROGS) $(if $(DO_MULTI),madwifi_multi); do \
- 		rm -f $(DESTDIR)$(BINDIR)/$$i; \
- 	done
--	for i in $(ALL:=.8); do \
--		rm -f $(DESTDIR)$(MANDIR)/man8/$$i; \
-+	for i in $(ALLPROGS); do \
-+		rm -f $(DESTDIR)$(MANDIR)/man8/$$i.8; \
- 	done
- 
- clean:
--	rm -f $(ALL) core a.out
-+	rm -f $(ALLPROGS) madwifi_multi *.o core a.out
---- a/tools/wlanconfig.c
-+++ b/tools/wlanconfig.c
-@@ -61,6 +61,7 @@
- #include "net80211/ieee80211.h"
- #include "net80211/ieee80211_crypto.h"
- #include "net80211/ieee80211_ioctl.h"
-+#include "do_multi.h"
- 
- /*
-  * These are taken from ieee80211_node.h
-@@ -100,7 +101,7 @@ size_t strlcat(char *, const char *, siz
- static int verbose = 0;
- 
- int
--main(int argc, char *argv[])
-+CMD(wlanconfig)(int argc, char *argv[])
- {
- 	const char *ifname, *cmd;
- 	unsigned char bnounit = 0;
---- a/tools/ath_info.c
-+++ b/tools/ath_info.c
-@@ -98,6 +98,7 @@
- #include <sys/mman.h>
- #include <endian.h>
- #include <byteswap.h>
-+#include "do_multi.h"
- 
- #undef ARRAY_SIZE
- #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-@@ -738,7 +739,8 @@ static void usage(const char *n)
- 		"unlawful radio transmissions!\n\n");
- }
- 
--int main(int argc, char *argv[])
-+int
-+CMD(athinfo)(int argc, char *argv[])
- {
- 	u_int32_t dev_addr;
- 	u_int16_t eeprom_header, srev, phy_rev_5ghz, phy_rev_2ghz;
diff --git a/package/madwifi/patches/104-autocreate_none.patch b/package/madwifi/patches/104-autocreate_none.patch
deleted file mode 100644
index b2181b68e2..0000000000
--- a/package/madwifi/patches/104-autocreate_none.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -516,7 +516,7 @@ ath_attach(u_int16_t devid, struct net_d
- 	HAL_STATUS status;
- 	int error = 0;
- 	unsigned int i;
--	int autocreatemode = IEEE80211_M_STA;
-+	int autocreatemode = -1;
- 	u_int8_t csz;
- 
- 	sc->devid = devid;
diff --git a/package/madwifi/patches/105-ratectl_attach.patch b/package/madwifi/patches/105-ratectl_attach.patch
deleted file mode 100644
index 80aad835e7..0000000000
--- a/package/madwifi/patches/105-ratectl_attach.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/net80211/ieee80211_rate.c
-+++ b/net80211/ieee80211_rate.c
-@@ -100,8 +100,18 @@ struct ath_ratectrl *ieee80211_rate_atta
- 		ieee80211_load_module(buf);
- 
- 	if (!ratectls[id].attach) {
--		printk(KERN_ERR "Error loading module \"%s\"\n", buf);
--		return NULL;
-+		/* pick the first available rate control module */
-+		printk(KERN_INFO "Rate control module \"%s\" not available\n", buf);
-+		for (id = 0; id < IEEE80211_RATE_MAX - 1; id++) {
-+			if (ratectls[id].attach)
-+				break;
-+		}
-+		if (!ratectls[id].attach) {
-+			printk(KERN_ERR "No rate control module available");
-+			return NULL;
-+		} else {
-+			printk(KERN_INFO "Using \"%s\" instead.\n", module_names[id]);
-+		}
- 	}
- 
- 	ctl = ratectls[id].attach(sc);
diff --git a/package/madwifi/patches/106-get_arch.patch b/package/madwifi/patches/106-get_arch.patch
deleted file mode 100644
index 3140f36799..0000000000
--- a/package/madwifi/patches/106-get_arch.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/scripts/get_arch.mk
-+++ b/scripts/get_arch.mk
-@@ -36,11 +36,14 @@ ifeq (,$(ARCH-y))
- $(Cannot determine ARCH)
- endif
- 
-+# Allow ARCH to be x86
-+ifneq (,$(CONFIG_X86))
-+ifeq (x86,$(ARCH))
-+ARCH-y = $(ARCH)
-+endif
-+endif
-+
- # Don't allow ARCH to be overridden by a different value.
- ifeq (,$(ARCH))
- ARCH = $(ARCH-y)
--else
--ifneq ($(ARCH),$(ARCH-y))
--$(error ARCH mismatch: supplied "$(ARCH)", determined "$(ARCH-y)")
--endif
- endif
diff --git a/package/madwifi/patches/111-minstrel_crash.patch b/package/madwifi/patches/111-minstrel_crash.patch
deleted file mode 100644
index 975bc4e94a..0000000000
--- a/package/madwifi/patches/111-minstrel_crash.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -393,6 +393,9 @@ ath_rate_get_mrr(struct ath_softc *sc, s
- 		struct minstrel_node *sn = ATH_NODE_MINSTREL(an);
- 		int rc1, rc2, rc3;         /* Index into the rate table, so for example, it is  0..11 */
- 
-+		if (sn->num_rates <= 0)
-+			return;
-+
- 		if (sn->is_sampling) {
- 			sn->is_sampling = 0;
- 			if (sn->rs_sample_rate_slower)
diff --git a/package/madwifi/patches/113-no_ibss_pwrsave.patch b/package/madwifi/patches/113-no_ibss_pwrsave.patch
deleted file mode 100644
index af23ceb7a8..0000000000
--- a/package/madwifi/patches/113-no_ibss_pwrsave.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/net80211/ieee80211_scan.c
-+++ b/net80211/ieee80211_scan.c
-@@ -291,7 +291,8 @@ scan_restart_pwrsav(unsigned long arg)
- 	struct ieee80211com *ic = vap->iv_ic;
- 	int delay;
- 
--	ieee80211_sta_pwrsave(vap, 1);
-+	if (vap->iv_opmode != IEEE80211_M_IBSS)
-+	    ieee80211_sta_pwrsave(vap, 1);
- 	/*
- 	 * Use an initial 1ms delay to ensure the null
- 	 * data frame has a chance to go out.
diff --git a/package/madwifi/patches/122-replayfail_workaround.patch b/package/madwifi/patches/122-replayfail_workaround.patch
deleted file mode 100644
index c4eb28c947..0000000000
--- a/package/madwifi/patches/122-replayfail_workaround.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/net80211/ieee80211_linux.c
-+++ b/net80211/ieee80211_linux.c
-@@ -331,6 +331,9 @@ ieee80211_notify_replay_failure(struct i
- 		k->wk_cipher->ic_name, k->wk_keyix,
- 		(unsigned long long)rsc);
- 
-+	/* disabled for now due to bogus events for unknown reasons */
-+	return;
-+
- 	/* TODO: needed parameters: count, keyid, key type, src address, TSC */
- 	snprintf(buf, sizeof(buf), "%s(keyid=%d %scast addr=" MAC_FMT ")", tag,
- 		k->wk_keyix,
diff --git a/package/madwifi/patches/123-ccmp_checks.patch b/package/madwifi/patches/123-ccmp_checks.patch
deleted file mode 100644
index 6178a3f786..0000000000
--- a/package/madwifi/patches/123-ccmp_checks.patch
+++ /dev/null
@@ -1,95 +0,0 @@
---- a/net80211/ieee80211_crypto_ccmp.c
-+++ b/net80211/ieee80211_crypto_ccmp.c
-@@ -115,6 +115,7 @@ ccmp_attach(struct ieee80211vap *vap, st
- /* This function (crypto_alloc_foo might sleep. Therefore:
-  * Context: process
-  */
-+#ifdef CONFIG_CRYPTO
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
- 	ctx->cc_tfm = crypto_alloc_tfm("aes", 0);
- #else
-@@ -123,7 +124,8 @@ ccmp_attach(struct ieee80211vap *vap, st
- 	if (IS_ERR(ctx->cc_tfm))
- 		ctx->cc_tfm = NULL;
- #endif
--	
-+#endif
-+
- 	if (ctx->cc_tfm == NULL) {
- 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO,
- 				"%s: unable to load kernel AES crypto support\n",
-@@ -138,12 +140,14 @@ ccmp_detach(struct ieee80211_key *k)
- {
- 	struct ccmp_ctx *ctx = k->wk_private;
- 
-+#ifdef CONFIG_CRYPTO
- 	if (ctx->cc_tfm != NULL)
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
- 		crypto_free_tfm(ctx->cc_tfm);
- #else
- 		crypto_free_cipher(ctx->cc_tfm);
- #endif
-+#endif
- 	FREE(ctx, M_DEVBUF);
- 
- 	_MOD_DEC_USE(THIS_MODULE);
-@@ -169,7 +173,9 @@ ccmp_setkey(struct ieee80211_key *k)
- 			return 0;
- 		}
- 
-+#ifdef CONFIG_CRYPTO
- 		crypto_cipher_setkey(ctx->cc_tfm, k->wk_key, k->wk_keylen);
-+#endif
- 	}
- 
- 	return 1;
-@@ -324,6 +330,7 @@ xor_block(u8 *b, const u8 *a, size_t len
- static void
- rijndael_encrypt(struct crypto_cipher *tfm, const void *src, void *dst)
- {
-+#ifdef CONFIG_CRYPTO
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
- 	crypto_cipher_encrypt_one(tfm, dst, src);
- #else
-@@ -339,6 +346,7 @@ rijndael_encrypt(struct crypto_cipher *t
- 	sg_dst.length = AES_BLOCK_LEN;
- 	crypto_cipher_encrypt(tfm, &sg_dst, &sg_src, AES_BLOCK_LEN);
- #endif
-+#endif
- }
- 
- /*
-@@ -475,6 +483,9 @@ ccmp_encrypt(struct ieee80211_key *key,
- 	uint8_t *mic, *pos;
- 	u_int space;
- 
-+	if (ctx->cc_tfm == NULL)
-+		return 0;
-+
- 	ctx->cc_vap->iv_stats.is_crypto_ccmp++;
- 
- 	skb = skb0;
-@@ -589,6 +600,9 @@ ccmp_decrypt(struct ieee80211_key *key,
- 	uint8_t *pos, *mic;
- 	u_int space;
- 
-+	if (ctx->cc_tfm == NULL)
-+		return 0;
-+
- 	ctx->cc_vap->iv_stats.is_crypto_ccmp++;
- 
- 	skb = skb0;
---- a/Makefile
-+++ b/Makefile
-@@ -192,11 +192,4 @@ endif
- 	    exit 1; \
- 	fi
- 	
--	@# check crypto support is enabled
--	@if [ -z "$(CONFIG_CRYPTO)" ]; then \
--	    echo "FAILED"; \
--	    echo "Please enable crypto API."; \
--	    exit 1; \
--	fi
--	
- 	@echo "ok."
diff --git a/package/madwifi/patches/124-linux24_compat.patch b/package/madwifi/patches/124-linux24_compat.patch
deleted file mode 100644
index 88601a4c71..0000000000
--- a/package/madwifi/patches/124-linux24_compat.patch
+++ /dev/null
@@ -1,202 +0,0 @@
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -126,6 +126,11 @@ typedef void irqreturn_t;
- #define ATH_GET_NETDEV_DEV(ndev)	((ndev)->class_dev.dev)
- #endif
- 
-+#ifndef NETDEV_TX_OK
-+#define NETDEV_TX_OK    0
-+#define NETDEV_TX_BUSY  1
-+#endif
-+
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23)
- static inline struct net_device *_alloc_netdev(int sizeof_priv, const char *mask,
- 					       void (*setup)(struct net_device *))
---- a/ath/if_ath_radar.c
-+++ b/ath/if_ath_radar.c
-@@ -92,6 +92,13 @@
- #define nofloat_pct(_value, _pct) \
- 	( (_value * (1000 + _pct)) / 1000 )
- 
-+#ifndef list_for_each_entry_reverse
-+#define list_for_each_entry_reverse(pos, head, member)			\
-+	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
-+	     prefetch(pos->member.prev), &pos->member != (head); 	\
-+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
-+#endif
-+
- struct radar_pattern_specification {
- 	/* The name of the rule/specification (i.e. what did we detect) */
- 	const char *name;
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -4705,6 +4705,46 @@ ath_beacon_setup(struct ath_softc *sc, s
- #undef USE_SHPREAMBLE
- }
- 
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-+{
-+	int ret;
-+	unsigned long flags;
-+
-+	local_irq_save(flags);
-+	ret = v->counter;
-+	if (likely(ret == old))
-+		v->counter = new;
-+	local_irq_restore(flags);
-+
-+	return ret;
-+}
-+
-+/**
-+ * atomic_add_unless - add unless the number is a given value
-+ * @v: pointer of type atomic_t
-+ * @a: the amount to add to v...
-+ * @u: ...unless v is equal to u.
-+ *
-+ * Atomically adds @a to @v, so long as it was not @u.
-+ * Returns non-zero if @v was not @u, and zero otherwise.
-+ */
-+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
-+{
-+	int c, old;
-+	c = atomic_read(v);
-+	for (;;) {
-+		if (unlikely(c == (u)))
-+			break;
-+		old = atomic_cmpxchg((v), c, c + (a));
-+		if (likely(old == c))
-+			break;
-+		c = old;
-+	}
-+	return c != (u);
-+}
-+#endif
-+
- /*
-  * Generate beacon frame and queue cab data for a VAP.
-  */
---- /dev/null
-+++ b/net80211/sort.c
-@@ -0,0 +1,120 @@
-+/*
-+ * A fast, small, non-recursive O(nlog n) sort for the Linux kernel
-+ *
-+ * Jan 23 2005  Matt Mackall <mpm@selenic.com>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+
-+static void u32_swap(void *a, void *b, int size)
-+{
-+	u32 t = *(u32 *)a;
-+	*(u32 *)a = *(u32 *)b;
-+	*(u32 *)b = t;
-+}
-+
-+static void generic_swap(void *a, void *b, int size)
-+{
-+	char t;
-+
-+	do {
-+		t = *(char *)a;
-+		*(char *)a++ = *(char *)b;
-+		*(char *)b++ = t;
-+	} while (--size > 0);
-+}
-+
-+/**
-+ * sort - sort an array of elements
-+ * @base: pointer to data to sort
-+ * @num: number of elements
-+ * @size: size of each element
-+ * @cmp: pointer to comparison function
-+ * @swap: pointer to swap function or NULL
-+ *
-+ * This function does a heapsort on the given array. You may provide a
-+ * swap function optimized to your element type.
-+ *
-+ * Sorting time is O(n log n) both on average and worst-case. While
-+ * qsort is about 20% faster on average, it suffers from exploitable
-+ * O(n*n) worst-case behavior and extra memory requirements that make
-+ * it less suitable for kernel use.
-+ */
-+
-+static void sort(void *base, size_t num, size_t size,
-+	  int (*cmp)(const void *, const void *),
-+	  void (*swap)(void *, void *, int size))
-+{
-+	/* pre-scale counters for performance */
-+	int i = (num/2 - 1) * size, n = num * size, c, r;
-+
-+	if (!swap)
-+		swap = (size == 4 ? u32_swap : generic_swap);
-+
-+	/* heapify */
-+	for ( ; i >= 0; i -= size) {
-+		for (r = i; r * 2 + size < n; r  = c) {
-+			c = r * 2 + size;
-+			if (c < n - size && cmp(base + c, base + c + size) < 0)
-+				c += size;
-+			if (cmp(base + r, base + c) >= 0)
-+				break;
-+			swap(base + r, base + c, size);
-+		}
-+	}
-+
-+	/* sort */
-+	for (i = n - size; i >= 0; i -= size) {
-+		swap(base, base + i, size);
-+		for (r = 0; r * 2 + size < i; r = c) {
-+			c = r * 2 + size;
-+			if (c < i - size && cmp(base + c, base + c + size) < 0)
-+				c += size;
-+			if (cmp(base + r, base + c) >= 0)
-+				break;
-+			swap(base + r, base + c, size);
-+		}
-+	}
-+}
-+
-+EXPORT_SYMBOL(sort);
-+
-+#if 0
-+/* a simple boot-time regression test */
-+
-+int cmpint(const void *a, const void *b)
-+{
-+	return *(int *)a - *(int *)b;
-+}
-+
-+static int sort_test(void)
-+{
-+	int *a, i, r = 1;
-+
-+	a = kmalloc(1000 * sizeof(int), GFP_KERNEL);
-+	BUG_ON(!a);
-+
-+	printk("testing sort()\n");
-+
-+	for (i = 0; i < 1000; i++) {
-+		r = (r * 725861) % 6599;
-+		a[i] = r;
-+	}
-+
-+	sort(a, 1000, sizeof(int), cmpint, NULL);
-+
-+	for (i = 0; i < 999; i++)
-+		if (a[i] > a[i+1]) {
-+			printk("sort() failed!\n");
-+			break;
-+		}
-+
-+	kfree(a);
-+
-+	return 0;
-+}
-+
-+module_init(sort_test);
-+#endif
diff --git a/package/madwifi/patches/126-rxerr_frames.patch b/package/madwifi/patches/126-rxerr_frames.patch
deleted file mode 100644
index 762a7bc815..0000000000
--- a/package/madwifi/patches/126-rxerr_frames.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -6474,8 +6474,9 @@ ath_rx_tasklet(TQUEUE_ARG data)
- 			/*
- 			 * Reject error frames if we have no vaps that
- 			 * are operating in monitor mode.
-+			 * Reject empty frames as well
- 			 */
--			if (sc->sc_nmonvaps == 0)
-+			if ((sc->sc_nmonvaps == 0) || (rs->rs_datalen == 0))
- 				goto rx_next;
- 		}
- rx_accept:
diff --git a/package/madwifi/patches/200-no_debug.patch b/package/madwifi/patches/200-no_debug.patch
deleted file mode 100644
index 3f46ec88b4..0000000000
--- a/package/madwifi/patches/200-no_debug.patch
+++ /dev/null
@@ -1,408 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -42,7 +42,6 @@
-  * This software is derived from work of Atsushi Onoe; his contribution
-  * is greatly appreciated.
-  */
--#define	AR_DEBUG
- #include "if_ath_debug.h"
- #include "opt_ah.h"
- 
-@@ -368,8 +367,10 @@ static unsigned int ath_get_dfs_cac_time
- static void ath_set_dfs_cac_time(struct ieee80211com *, unsigned int seconds);
- 
- static unsigned int ath_test_radar(struct ieee80211com *);
--static unsigned int ath_dump_hal_map(struct ieee80211com *ic);
-+#ifdef AR_DEBUG
- 
-+static unsigned int ath_dump_hal_map(struct ieee80211com *ic);
-+#endif
- static u_int32_t ath_get_clamped_maxtxpower(struct ath_softc *sc);
- static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc, 
- 		u_int32_t new_clamped_maxtxpower);
-@@ -520,9 +521,11 @@ ath_attach(u_int16_t devid, struct net_d
- 	u_int8_t csz;
- 
- 	sc->devid = devid;
-+#ifdef AR_DEBUG
- 	ath_debug_global = (ath_debug & ATH_DEBUG_GLOBAL);
- 	sc->sc_debug 	 = (ath_debug & ~ATH_DEBUG_GLOBAL);
- 	DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
-+#endif
- 
- 	/* Allocate space for dynamically determined maximum VAP count */
- 	sc->sc_bslot = 
-@@ -1038,8 +1041,9 @@ ath_attach(u_int16_t devid, struct net_d
- 	ic->ic_vap_delete = ath_vap_delete;
- 
- 	ic->ic_test_radar           = ath_test_radar;
-+#ifdef AR_DEBUG
- 	ic->ic_dump_hal_map	    = ath_dump_hal_map;
--
-+#endif
- 	ic->ic_set_dfs_testmode     = ath_set_dfs_testmode;
- 	ic->ic_get_dfs_testmode     = ath_get_dfs_testmode;
- 
-@@ -1297,12 +1301,14 @@ ath_vap_create(struct ieee80211com *ic,
- 		/* If no default VAP debug flags are passed, allow a few to
- 		 * transfer down from the driver to new VAPs so we can have load
- 		 * time debugging for VAPs too. */
-+#ifdef AR_DEBUG
- 		vap->iv_debug = 0 |
- 			((sc->sc_debug & ATH_DEBUG_RATE) ? IEEE80211_MSG_XRATE  : 0) | 
- 			((sc->sc_debug & ATH_DEBUG_XMIT) ? IEEE80211_MSG_OUTPUT : 0) | 
- 			((sc->sc_debug & ATH_DEBUG_RECV) ? IEEE80211_MSG_INPUT  : 0) |
- 			0
- 			;
-+#endif
- 	}
- 	ic->ic_debug = (sc->sc_default_ieee80211_debug & IEEE80211_MSG_IC);
- 
-@@ -10496,9 +10502,11 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 				/* XXX validate? */
- 				sc->sc_ledpin = val;
- 				break;
-+#ifdef AR_DEBUG
- 			case ATH_DEBUG:
- 				sc->sc_debug 	 = (val & ~ATH_DEBUG_GLOBAL);
- 				ath_debug_global = (val &  ATH_DEBUG_GLOBAL);
-+#endif
- 				break;
- 			case ATH_TXANTENNA:
- 				/*
-@@ -10918,9 +10926,11 @@ ath_dynamic_sysctl_register(struct ath_s
- 	}
- 
- 	/* initialize values */
-+#ifdef AR_DEBUG
- 	ath_debug_global = (ath_debug & ATH_DEBUG_GLOBAL);
- 	sc->sc_debug 	 = (ath_debug & ~ATH_DEBUG_GLOBAL);
- 	sc->sc_default_ieee80211_debug = ieee80211_debug;
-+#endif
- 	sc->sc_txantenna = 0;		/* default to auto-selection */
- 	sc->sc_txintrperiod = ATH_TXQ_INTR_PERIOD;
- }
-@@ -11762,6 +11772,7 @@ ath_test_radar(struct ieee80211com *ic)
- }
- 
- /* This is called by a private ioctl (iwpriv) to dump the HAL obfuscation table */
-+#ifdef AR_DEBUG
- static unsigned int
- ath_dump_hal_map(struct ieee80211com *ic)
- {
-@@ -11770,7 +11781,7 @@ ath_dump_hal_map(struct ieee80211com *ic
- 	ath_hal_dump_map(sc->sc_ah);
- 	return 0;
- }
--
-+#endif
- /* If we are shutting down or blowing off the DFS channel availability check
-  * then we call this to stop the behavior before we take the rest of the
-  * necessary actions (such as a DFS reaction to radar). */
---- a/ath_rate/amrr/amrr.c
-+++ b/ath_rate/amrr/amrr.c
-@@ -70,7 +70,9 @@
- 
- #include "amrr.h"
- 
-+#ifdef AR_DEBUG
- #define	AMRR_DEBUG
-+#endif
- #ifdef AMRR_DEBUG
- #define	DPRINTF(sc, _fmt, ...) do {					\
- 	if (sc->sc_debug & 0x10)					\
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -117,7 +117,9 @@
- 
- #include "minstrel.h"
- 
-+#ifdef AR_DEBUG
- #define	MINSTREL_DEBUG
-+#endif
- #ifdef MINSTREL_DEBUG
- enum {
- 		ATH_DEBUG_RATE		= 0x00000010	/* rate control */
---- a/ath_rate/onoe/onoe.c
-+++ b/ath_rate/onoe/onoe.c
-@@ -66,7 +66,9 @@
- 
- #include "onoe.h"
- 
-+#ifdef AR_DEBUG
- #define	ONOE_DEBUG
-+#endif
- #ifdef ONOE_DEBUG
- enum {
- 	ATH_DEBUG_RATE	= 0x00000010,	/* rate control */
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -68,7 +68,9 @@
- 
- #include "sample.h"
- 
--#define	SAMPLE_DEBUG
-+#ifdef AR_DEBUG
-+#define SAMPLE_DEBUG
-+#endif
- #ifdef SAMPLE_DEBUG
- enum {
- 	ATH_DEBUG_RATE		= 0x00000010,	/* rate control */
---- a/tools/do_multi.c
-+++ b/tools/do_multi.c
-@@ -10,16 +10,20 @@ main(int argc, char *argv[])
- 
-     progname = basename(argv[0]);
- 
-+#ifdef AR_DEBUG
-     if(strcmp(progname, "80211debug") == 0)
- 	ret = a80211debug_init(argc, argv);
-+#endif
-     if(strcmp(progname, "80211stats") == 0)
- 	ret = a80211stats_init(argc, argv);
-     if(strcmp(progname, "athchans") == 0)
- 	ret = athchans_init(argc, argv);
-     if(strcmp(progname, "athctrl") == 0)
- 	ret =  athctrl_init(argc, argv);
-+#ifdef AR_DEBUG
-     if(strcmp(progname, "athdebug") == 0)
- 	ret =  athdebug_init(argc, argv);
-+#endif
-     if(strcmp(progname, "athkey") == 0)
- 	ret =  athkey_init(argc, argv);
-     if(strcmp(progname, "athstats") == 0)
---- a/tools/Makefile
-+++ b/tools/Makefile
-@@ -48,14 +48,16 @@ endif
- 
- all: compile
- 
-+DEBUG = -DAR_DEBUG
-+
- ALLPROGS=	athstats 80211stats athkey athchans athctrl \
--	athdebug 80211debug wlanconfig ath_info
-+	$(if $(DEBUG),athdebug 80211debug) wlanconfig ath_info
- 
- OBJS=	$(patsubst %,%.o,$(ALLPROGS))
- 
- INCS=	-I. -I../ath -I$(HAL) -I$(TOP) -I$(ATH_HAL)
- CFLAGS=	-g -O2 -Wall
--ALL_CFLAGS= $(CFLAGS) $(INCS)
-+ALL_CFLAGS= $(CFLAGS) $(INCS) $(DEBUG)
- LDFLAGS=
- 
- 
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -29,8 +29,6 @@
- #ifndef _NET80211_IEEE80211_LINUX_H_
- #define _NET80211_IEEE80211_LINUX_H_
- 
--#define	IEEE80211_DEBUG
--#define	IEEE80211_DEBUG_REFCNT			/* Node reference count debugging */
- /* #define ATH_DEBUG_SPINLOCKS */		/* announce before spinlocking */
- 
- #include <linux/wireless.h>
---- a/Makefile.inc
-+++ b/Makefile.inc
-@@ -147,8 +147,9 @@ ATH_RATE=	$(TOP)/ath_rate
- # 
- TOOLS=  $(TOP)/tools 
- 
--WARNINGS = -Werror
--COPTS+= $(WARNINGS)
-+WARNINGS = -Wno-unused
-+# DEBUG = -DAR_DEBUG -DIEEE80211_DEBUG
-+COPTS+= $(WARNINGS) $(DEBUG)
- INCS=	-include $(TOP)/include/compat.h -I$(TOP)/include
- 
- # TARGET defines the target platform architecture. It must match one of
---- a/ath/if_ath_radar.c
-+++ b/ath/if_ath_radar.c
-@@ -19,8 +19,6 @@
-  * $Id: if_ath_radar.c 2464 2007-06-15 22:51:56Z mtaylor $
-  */
- #include "opt_ah.h"
--
--#define	AR_DEBUG
- #include "if_ath_debug.h"
- 
- #ifndef AUTOCONF_INCLUDED
-@@ -56,8 +54,6 @@
- #include <net80211/if_llc.h>
- #endif
- 
--#define	AR_DEBUG
--
- #include "net80211/if_athproto.h"
- #include "if_athvar.h"
- 
---- a/ath/if_ath_hal.h
-+++ b/ath/if_ath_hal.h
-@@ -1081,6 +1081,7 @@ static inline HAL_BOOL ath_hal_disable(s
- 
-            tail -f /var/log/messages | sed -f hal_unmangle.sed 
-  */
-+#ifdef AR_DEBUG
- static inline void ath_hal_dump_map(struct ath_hal *ah)
- {
- #ifdef CONFIG_KALLSYMS
-@@ -1345,7 +1346,7 @@ static inline void ath_hal_dump_map(stru
- #endif				/* #ifndef CONFIG_KALLSYMS */
- 
- }
--
-+#endif
- #include "if_ath_hal_wrappers.h"
- 
- #endif				/* #ifndef _IF_ATH_HAL_H_ */
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -492,9 +492,10 @@ struct ieee80211com {
- 	/* inject a fake radar signal -- used while on a 802.11h DFS channels */
- 	unsigned int (*ic_test_radar)(struct ieee80211com *);
- 
-+#ifdef AR_DEBUG
- 	/* dump HAL */
- 	unsigned int (*ic_dump_hal_map)(struct ieee80211com *);
--
-+#endif
- 	/* DFS channel availability check time (in seconds) */
- 	void (*ic_set_dfs_cac_time)(struct ieee80211com *, unsigned int);
- 	unsigned int (*ic_get_dfs_cac_time)(struct ieee80211com *);
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -1548,6 +1548,7 @@ ieee80211_get_txcont_power(struct net_de
- 	return 0;
- }
- 
-+#ifdef AR_DEBUG
- static int 
- ieee80211_ioctl_hal_map(struct net_device *dev, struct iw_request_info *info,
-        void *w, char *extra)
-@@ -1558,7 +1559,7 @@ ieee80211_ioctl_hal_map(struct net_devic
-        params[0] = ic->ic_dump_hal_map(ic);
-        return 0;
- }
--
-+#endif
- 
- static int
- ieee80211_ioctl_radar(struct net_device *dev, struct iw_request_info *info,
-@@ -5258,8 +5259,10 @@ static const struct iw_priv_args ieee802
- 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,   "getwmmparams" },
- 	{ IEEE80211_IOCTL_RADAR,
- 	  0, 0, "doth_radar" },
-+#ifdef AR_DEBUG
- 	{ IEEE80211_IOCTL_HALMAP,
- 	  0, 0, "dump_hal_map" },
-+#endif
- 	/*
- 	 * These depends on sub-ioctl support which added in version 12.
- 	 */
-@@ -5695,7 +5698,9 @@ static const iw_handler ieee80211_priv_h
- 	set_priv(IEEE80211_IOCTL_SETMLME, ieee80211_ioctl_setmlme),
- 	set_priv(IEEE80211_IOCTL_SETKEY, ieee80211_ioctl_setkey),
- 	set_priv(IEEE80211_IOCTL_DELKEY, ieee80211_ioctl_delkey),
-+#ifdef AR_DEBUG
- 	set_priv(IEEE80211_IOCTL_HALMAP, ieee80211_ioctl_hal_map),
-+#endif
- 	set_priv(IEEE80211_IOCTL_ADDMAC, ieee80211_ioctl_addmac),
- 	set_priv(IEEE80211_IOCTL_DELMAC, ieee80211_ioctl_delmac),
- 	set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac),
---- a/ath/if_ath_debug.h
-+++ b/ath/if_ath_debug.h
-@@ -54,6 +54,10 @@ enum {
- 	ATH_DEBUG_GLOBAL	= (ATH_DEBUG_SKB|ATH_DEBUG_SKB_REF)
- };
- 
-+#define	EPRINTF(_sc, _fmt, ...) \
-+		printk(KERN_ERR "%s: %s: " _fmt, \
-+			SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__)
-+
- #ifdef AR_DEBUG
- 
- /* DEBUG-ONLY DEFINITIONS */
-@@ -68,20 +72,9 @@ enum {
- 		ath_keyprint((_sc), __func__, _ix, _hk, _mac);		\
- } while (0)
- 
--#else /* #ifdef AR_DEBUG */
--
--#define	DFLAG_ISSET(sc, _m)		0
--#define	DPRINTF(sc, _m, _fmt, ...)
--#define	KEYPRINTF(sc, k, ix, mac)
--
--#endif /* #ifdef AR_DEBUG */
- 
- #define	IFF_DUMPPKTS(_sc, _m)   DFLAG_ISSET((_sc), (_m))
- 
--#define	EPRINTF(_sc, _fmt, ...) \
--		printk(KERN_ERR "%s: %s: " _fmt, \
--			SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__)
--
- #define	WPRINTF(_sc, _fmt, ...) \
- 		printk(KERN_WARNING "%s: %s: " _fmt, \
- 			SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__)
-@@ -89,5 +82,14 @@ enum {
- #define	IPRINTF(_sc, _fmt, ...) \
- 		printk(KERN_INFO "%s: %s: " _fmt, \
- 			SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__)
-+#else
-+#define	DFLAG_ISSET(sc, _m)		0
-+#define	DPRINTF(sc, _m, _fmt, ...)
-+#define	KEYPRINTF(sc, k, ix, mac)
-+#define WPRINTF(...)
-+#define IPRINTF(...)
-+#define IFF_DUMPPKTS(...) 0
-+
-+#endif
- 
- #endif /* #ifndef _IF_ATH_DEBUG_H_ */
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -920,6 +920,9 @@ node_cleanup(struct ieee80211_node *ni)
- 	ni->ni_rxkeyoff = 0;
- }
- 
-+#ifndef IEEE80211_DEBUG
-+#define node_print_message(...) do {} while(0)
-+#else
- static void node_print_message(
- 		u_int32_t flags,
- 		int show_counter, 
-@@ -972,7 +975,7 @@ static void node_print_message(
- 			adjusted_refcount);
- 	va_end(args);
- }
--EXPORT_SYMBOL(node_print_message);
-+#endif
- 
- static void
- #ifdef IEEE80211_DEBUG_REFCNT
---- a/ath/if_ath_pci.c
-+++ b/ath/if_ath_pci.c
-@@ -134,8 +134,10 @@ ath_pci_probe(struct pci_dev *pdev, cons
- 	u16 vdevice;
- 	int i;
- 
--	if (pci_enable_device(pdev))
-+	if (pci_enable_device(pdev)) {
-+		printk(KERN_ERR "%s: failed to enable PCI device\n", dev_info);
- 		return -EIO;
-+	}
- 
- 	/* XXX 32-bit addressing only */
- 	if (pci_set_dma_mask(pdev, 0xffffffff)) {
-@@ -244,8 +246,10 @@ ath_pci_probe(struct pci_dev *pdev, cons
- 		sc->aps_sc.sc_ledpin = 1;
- 	}
- 
--	if (ath_attach(vdevice, dev, NULL) != 0)
-+	if ((i = ath_attach(vdevice, dev, NULL)) != 0) {
-+		printk(KERN_ERR "%s: ath_attach failed: %d\n", dev_info, i);
- 		goto bad4;
-+	}
- 
- 	athname = ath_hal_probe(id->vendor, vdevice);
- 	printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
diff --git a/package/madwifi/patches/201-debug_fix.patch b/package/madwifi/patches/201-debug_fix.patch
deleted file mode 100644
index bcfbba82c6..0000000000
--- a/package/madwifi/patches/201-debug_fix.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/ath_hal/ah_os.c
-+++ b/ath_hal/ah_os.c
-@@ -65,7 +65,7 @@
- #include <ah_os.h>
- 
- #ifdef AH_DEBUG
--static	int ath_hal_debug = 0;
-+static	int ath_hal_debug = 99;
- #endif
- 
- int	ath_hal_dma_beacon_response_time = 2;	/* in TUs */
-@@ -327,6 +327,8 @@ EXPORT_SYMBOL(OS_MARK);
-  * useful for debugging and figuring out, which hal function sets which 
-  * registers */
- char *ath_hal_func = NULL;
-+EXPORT_SYMBOL(ath_hal_func);
-+
- #endif
- 
- /*
diff --git a/package/madwifi/patches/202-debug_variables.patch b/package/madwifi/patches/202-debug_variables.patch
deleted file mode 100644
index 33e6efad13..0000000000
--- a/package/madwifi/patches/202-debug_variables.patch
+++ /dev/null
@@ -1,204 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -453,8 +453,8 @@ MODULE_PARM_DESC(autocreate, "Create ath
- MODULE_PARM_DESC(ratectl, "Rate control algorithm [amrr|minstrel|onoe|sample], "
- 		"defaults to '" DEF_RATE_CTL "'");
- 
--static int	ath_debug = 0;
- #ifdef AR_DEBUG
-+static int	ath_debug = 0;
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
- MODULE_PARM(ath_debug, "i");
- #else
-@@ -465,8 +465,8 @@ static void ath_printrxbuf(const struct
- static void ath_printtxbuf(const struct ath_buf *, int);
- #endif /* defined(AR_DEBUG) */
- 
--static int	ieee80211_debug = 0;
- #ifdef AR_DEBUG
-+static int	ieee80211_debug = 0;
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
- MODULE_PARM(ieee80211_debug, "i");
- #else
-@@ -1565,7 +1565,9 @@ ath_vap_delete(struct ieee80211vap *vap)
- void
- ath_suspend(struct net_device *dev)
- {
-+#ifdef AR_DEBUG
- 	struct ath_softc *sc = dev->priv;
-+#endif
- 
- 	DPRINTF(sc, ATH_DEBUG_ANY, "flags=%x\n", dev->flags);
- 	ath_stop(dev);
-@@ -1574,7 +1576,9 @@ ath_suspend(struct net_device *dev)
- void
- ath_resume(struct net_device *dev)
- {
-+#ifdef AR_DEBUG
- 	struct ath_softc *sc = dev->priv;
-+#endif
- 
- 	DPRINTF(sc, ATH_DEBUG_ANY, "flags=%x\n", dev->flags);
- 	ath_init(dev);
-@@ -4019,7 +4023,9 @@ static void
- ath_key_update_begin(struct ieee80211vap *vap)
- {
- 	struct net_device *dev = vap->iv_ic->ic_dev;
-+#ifdef AR_DEBUG
- 	struct ath_softc *sc = dev->priv;
-+#endif
- 
- 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "Begin\n");
- 	/*
-@@ -4040,7 +4046,9 @@ static void
- ath_key_update_end(struct ieee80211vap *vap)
- {
- 	struct net_device *dev = vap->iv_ic->ic_dev;
-+#ifdef AR_DEBUG
- 	struct ath_softc *sc = dev->priv;
-+#endif
- 
- 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "End\n");
- 	netif_wake_queue(dev);
-@@ -6218,7 +6226,9 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 	struct sk_buff *skb, int subtype, int rssi, u_int64_t rtsf)
- {
- 	struct ath_softc *sc = vap->iv_ic->ic_dev->priv;
-+#ifdef AR_DEBUG
-         struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
-+#endif
- 	struct ieee80211_node * ni = ni_or_null;
- 	u_int64_t hw_tsf, beacon_tsf;
- 	u_int32_t hw_tu, beacon_tu, intval;
-@@ -8382,7 +8392,9 @@ ath_tx_timeout(struct net_device *dev)
- static void
- ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
- {
-+#ifdef AR_DEBUG
- 	struct ath_hal *ah = sc->sc_ah;
-+#endif
- 	struct ath_buf *bf;
- 	/*
- 	 * NB: this assumes output has been stopped and
-@@ -11002,6 +11014,7 @@ ath_announce(struct net_device *dev)
- 		strncat(m, b, MLEN);
- 	}
- 	strncat(m, "\n", MLEN);
-+#ifdef AR_DEBUG
- 	if (1 /* bootverbose */) {
- 		unsigned int i;
- 		for (i = 0; i <= WME_AC_VO; i++) {
-@@ -11014,6 +11027,7 @@ ath_announce(struct net_device *dev)
- 			sc->sc_cabq->axq_qnum);
- 		IPRINTF(sc, "Use hw queue %u for beacons\n", sc->sc_bhalq);
- 	}
-+#endif
- #undef HAL_MODE_DUALBAND
- }
-  
---- a/ath/if_ath_radar.c
-+++ b/ath/if_ath_radar.c
-@@ -156,7 +156,9 @@ static struct radar_pattern_specificatio
- #endif
- };
- 
-+#ifdef AR_DEBUG
- static u_int32_t interval_to_frequency(u_int32_t pri);
-+#endif
- 
- /* Returns true if radar detection is enabled. */
- int ath_radar_is_enabled(struct ath_softc *sc)
-@@ -229,7 +231,9 @@ int ath_radar_update(struct ath_softc *s
- {
- 
- 	struct ath_hal *ah = sc->sc_ah;
-+#ifdef AR_DEBUG
- 	struct net_device *dev = sc->sc_dev;
-+#endif
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	int required = 0;
- 
-@@ -366,6 +370,7 @@ static struct ath_rp *pulse_prev(struct
- #define MR_FAIL_MIN_PERIOD	4
- #define MR_FAIL_MAX_PERIOD	5
- 
-+#ifdef AR_DEBUG
- static const char* get_match_result_desc(u_int32_t code) {
- 	switch (code) {
- 	case MR_MATCH:
-@@ -384,6 +389,7 @@ static const char* get_match_result_desc
- 		return "unknown";
- 	}
- }
-+#endif
- 
- static int32_t match_radar(
- 	u_int32_t matched, 
-@@ -775,7 +781,10 @@ static HAL_BOOL rp_analyse_short_pulse(
- 	struct ath_softc *sc, struct ath_rp *last_pulse, 
- 	u_int32_t *index, u_int32_t *pri, u_int32_t *matching_pulses, 
- 	u_int32_t *missed_pulses, u_int32_t *noise_pulses)
--{ struct net_device *dev = sc->sc_dev;
-+{
-+#ifdef AR_DEBUG
-+	struct net_device *dev = sc->sc_dev;
-+#endif
- 	int i;
- 	int best_index = -1;
- 	unsigned int best_matched = 0;
-@@ -1217,6 +1226,7 @@ static HAL_BOOL rp_analyse_short_pulse(
- 	return (-1 != best_index) ? AH_TRUE : AH_FALSE;
- }
- 
-+#ifdef AR_DEBUG
- static u_int32_t interval_to_frequency(u_int32_t interval)
- {
- 	/* Calculate BRI from PRI */
-@@ -1224,6 +1234,7 @@ static u_int32_t interval_to_frequency(u
- 	/* Round to nearest multiple of 50 */
- 	return frequency + ((frequency % 50) >= 25 ? 50 : 0) - (frequency % 50);
- }
-+#endif
- 
- #ifdef ATH_RADAR_LONG_PULSE
- static const char* get_longpulse_desc(int lp) {
-@@ -1580,7 +1591,9 @@ void ath_rp_done(struct ath_softc *sc)
- void ath_rp_record(struct ath_softc *sc, u_int64_t tsf, u_int8_t rssi, 
- 			    u_int8_t width, HAL_BOOL is_simulated)
- {
-+#ifdef AR_DEBUG
- 	struct net_device *dev = sc->sc_dev;
-+#endif
- 	struct ath_rp *pulse;
- 
- 	DPRINTF(sc, ATH_DEBUG_DOTHPULSES, "%s: ath_rp_record: "
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -931,7 +931,9 @@ ath_proc_read_nodes(struct ieee80211vap
- 			    (struct ieee80211_node_table *) &vap->iv_ic->ic_sta;
- 		unsigned int x = 0;
- 		unsigned int this_tp, this_prob, this_eprob;
-+#ifdef AR_DEBUG
- 			struct ath_softc *sc = vap->iv_ic->ic_dev->priv;;
-+#endif
- 
- 		IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
- 		TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
---- a/net80211/ieee80211_scan_ap.c
-+++ b/net80211/ieee80211_scan_ap.c
-@@ -731,6 +731,7 @@ pick_channel(struct ieee80211_scan_state
- 
- 	sort(chans, ss_last, sizeof(*chans), pc_cmp, pc_swap);
- 
-+#ifdef IEEE80211_DEBUG
- 	for (i = 0; i < ss_last; i++) {
- 		int chan = ieee80211_chan2ieee(ic, chans[i].chan);
- 
-@@ -742,6 +743,7 @@ pick_channel(struct ieee80211_scan_state
- 				!!IEEE80211_ARE_CHANS_SAME_MODE(chans[i].chan, 
- 					ic->ic_bsschan));
- 	}
-+#endif
- 
- 	best = NULL;
- 	best_rssi = 0xff; /* If signal is bigger than 0xff, we'd be melting. */
diff --git a/package/madwifi/patches/300-napi_polling.patch b/package/madwifi/patches/300-napi_polling.patch
deleted file mode 100644
index bde7684946..0000000000
--- a/package/madwifi/patches/300-napi_polling.patch
+++ /dev/null
@@ -1,536 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -184,7 +184,11 @@ static void ath_recv_mgmt(struct ieee802
- 	struct sk_buff *, int, int, u_int64_t);
- static void ath_setdefantenna(struct ath_softc *, u_int);
- static struct ath_txq *ath_txq_setup(struct ath_softc *, int, int);
--static void ath_rx_tasklet(TQUEUE_ARG);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+static int ath_rx_poll(struct napi_struct *napi, int budget);
-+#else
-+static int ath_rx_poll(struct net_device *dev, int *budget);
-+#endif
- static int ath_hardstart(struct sk_buff *, struct net_device *);
- static int ath_mgtstart(struct ieee80211com *, struct sk_buff *);
- #ifdef ATH_SUPERG_COMP
-@@ -376,6 +380,9 @@ static u_int32_t ath_set_clamped_maxtxpo
- 		u_int32_t new_clamped_maxtxpower);
- static u_int32_t ath_get_real_maxtxpower(struct ath_softc *sc);
- 
-+static void ath_poll_disable(struct net_device *dev);
-+static void ath_poll_enable(struct net_device *dev);
-+
- /* calibrate every 30 secs in steady state but check every second at first. */
- static int ath_calinterval = ATH_SHORT_CALINTERVAL;
- static int ath_countrycode = CTRY_DEFAULT;	/* country code */
-@@ -547,7 +554,6 @@ ath_attach(u_int16_t devid, struct net_d
- 
- 	atomic_set(&sc->sc_txbuf_counter, 0);
- 
--	ATH_INIT_TQUEUE(&sc->sc_rxtq,     ath_rx_tasklet,	dev);
- 	ATH_INIT_TQUEUE(&sc->sc_txtq,	  ath_tx_tasklet,	dev);
- 	ATH_INIT_TQUEUE(&sc->sc_bmisstq,  ath_bmiss_tasklet,	dev);
- 	ATH_INIT_TQUEUE(&sc->sc_bstucktq, ath_bstuck_tasklet,	dev);
-@@ -821,6 +827,12 @@ ath_attach(u_int16_t devid, struct net_d
- 	dev->set_mac_address = ath_set_mac_address;
- 	dev->change_mtu = ath_change_mtu;
- 	dev->tx_queue_len = ATH_TXBUF - ATH_TXBUF_MGT_RESERVED;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+	netif_napi_add(dev, &sc->sc_napi, ath_rx_poll, 64);
-+#else
-+	dev->poll = ath_rx_poll;
-+	dev->weight = 64;
-+#endif
- #ifdef USE_HEADERLEN_RESV
- 	dev->hard_header_len += sizeof(struct ieee80211_qosframe) +
- 				sizeof(struct llc) +
-@@ -2220,6 +2232,7 @@ ath_intr(int irq, void *dev_id, struct p
- 		(status & HAL_INT_GLOBAL)	? " HAL_INT_GLOBAL"	: ""
- 		);
- 
-+	sc->sc_isr = status;
- 	status &= sc->sc_imask;			/* discard unasked for bits */
- 	/* As soon as we know we have a real interrupt we intend to service, 
- 	 * we will check to see if we need an initial hardware TSF reading. 
-@@ -2277,7 +2290,21 @@ ath_intr(int irq, void *dev_id, struct p
- 		}
- 		if (status & (HAL_INT_RX | HAL_INT_RXPHY)) {
- 			ath_uapsd_processtriggers(sc, hw_tsf);
--			ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, &needmark);
-+			sc->sc_isr &= ~HAL_INT_RX;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+			if (netif_rx_schedule_prep(dev, &sc->sc_napi))
-+#else
-+			if (netif_rx_schedule_prep(dev))
-+#endif
-+			{
-+				sc->sc_imask &= ~HAL_INT_RX;
-+				ath_hal_intrset(ah, sc->sc_imask);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+				__netif_rx_schedule(dev, &sc->sc_napi);
-+#else
-+				__netif_rx_schedule(dev);
-+#endif
-+			}
- 		}
- 		if (status & HAL_INT_TX) {
- #ifdef ATH_SUPERG_DYNTURBO
-@@ -2303,6 +2330,11 @@ ath_intr(int irq, void *dev_id, struct p
- 				}
- 			}
- #endif
-+			/* disable transmit interrupt */
-+			sc->sc_isr &= ~HAL_INT_TX;
-+			ath_hal_intrset(ah, sc->sc_imask & ~HAL_INT_TX);
-+			sc->sc_imask &= ~HAL_INT_TX;
-+
- 			ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark);
- 		}
- 		if (status & HAL_INT_BMISS) {
-@@ -2515,6 +2547,7 @@ ath_init(struct net_device *dev)
- 	if (sc->sc_tx99 != NULL)
- 		sc->sc_tx99->start(sc->sc_tx99);
- #endif
-+	ath_poll_enable(dev);
- 
- done:
- 	ATH_UNLOCK(sc);
-@@ -2555,6 +2588,9 @@ ath_stop_locked(struct net_device *dev)
- 		if (sc->sc_tx99 != NULL)
- 			sc->sc_tx99->stop(sc->sc_tx99);
- #endif
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+		ath_poll_disable(dev);
-+#endif
- 		netif_stop_queue(dev);	/* XXX re-enabled by ath_newstate */
- 		dev->flags &= ~IFF_RUNNING;	/* NB: avoid recursion */
- 		ieee80211_stop_running(ic);	/* stop all VAPs */
-@@ -4013,12 +4049,47 @@ ath_key_set(struct ieee80211vap *vap, co
- 	return ath_keyset(sc, k, mac, vap->iv_bss);
- }
- 
-+static void ath_poll_disable(struct net_device *dev)
-+{
-+	struct ath_softc *sc = dev->priv;
-+
-+	/*
-+	 * XXX Using in_softirq is not right since we might
-+	 * be called from other soft irq contexts than
-+	 * ath_rx_poll
-+	 */
-+	if (!in_softirq()) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+		napi_disable(&sc->sc_napi);
-+#else
-+		netif_poll_disable(dev);
-+#endif
-+	}
-+}
-+
-+static void ath_poll_enable(struct net_device *dev)
-+{
-+	struct ath_softc *sc = dev->priv;
-+
-+	/* NB: see above */
-+	if (!in_softirq()) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+		napi_enable(&sc->sc_napi);
-+#else
-+		netif_poll_enable(dev);
-+#endif
-+	}
-+}
-+
-+
- /*
-  * Block/unblock tx+rx processing while a key change is done.
-  * We assume the caller serializes key management operations
-  * so we only need to worry about synchronization with other
-  * uses that originate in the driver.
-  */
-+#define	IS_UP(_dev) \
-+	(((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
- static void
- ath_key_update_begin(struct ieee80211vap *vap)
- {
-@@ -4032,14 +4103,9 @@ ath_key_update_begin(struct ieee80211vap
- 	 * When called from the rx tasklet we cannot use
- 	 * tasklet_disable because it will block waiting
- 	 * for us to complete execution.
--	 *
--	 * XXX Using in_softirq is not right since we might
--	 * be called from other soft irq contexts than
--	 * ath_rx_tasklet.
- 	 */
--	if (!in_softirq())
--		tasklet_disable(&sc->sc_rxtq);
--	netif_stop_queue(dev);
-+	if (IS_UP(vap->iv_dev))
-+		netif_stop_queue(dev);
- }
- 
- static void
-@@ -4051,9 +4117,9 @@ ath_key_update_end(struct ieee80211vap *
- #endif
- 
- 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "End\n");
--	netif_wake_queue(dev);
--	if (!in_softirq())		/* NB: see above */
--		tasklet_enable(&sc->sc_rxtq);
-+
-+	if (IS_UP(vap->iv_dev))
-+		netif_wake_queue(dev);
- }
- 
- /*
-@@ -6360,15 +6426,25 @@ ath_setdefantenna(struct ath_softc *sc,
- 	sc->sc_rxotherant = 0;
- }
- 
--static void
--ath_rx_tasklet(TQUEUE_ARG data)
-+static int
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+ath_rx_poll(struct napi_struct *napi, int budget)
-+#else
-+ath_rx_poll(struct net_device *dev, int *budget)
-+#endif
- {
- #define	PA2DESC(_sc, _pa) \
- 	((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
- 		((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
--	struct net_device *dev = (struct net_device *)data;
--	struct ath_buf *bf;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+	struct ath_softc *sc = container_of(napi, struct ath_softc, sc_napi);
-+	struct net_device *dev = sc->sc_dev;
-+	u_int rx_limit = budget;
-+#else
- 	struct ath_softc *sc = dev->priv;
-+	u_int rx_limit = min(dev->quota, *budget);
-+#endif
-+	struct ath_buf *bf;
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc ? sc->sc_ah : NULL;
- 	struct ath_desc *ds;
-@@ -6378,8 +6454,10 @@ ath_rx_tasklet(TQUEUE_ARG data)
- 	unsigned int len;
- 	int type;
- 	u_int phyerr;
-+	u_int processed = 0, early_stop = 0;
- 
- 	DPRINTF(sc, ATH_DEBUG_RX_PROC, "invoked\n");
-+process_rx_again:
- 	do {
- 		bf = STAILQ_FIRST(&sc->sc_rxbuf);
- 		if (bf == NULL) {		/* XXX ??? can this happen */
-@@ -6403,6 +6481,15 @@ ath_rx_tasklet(TQUEUE_ARG data)
- 			/* NB: never process the self-linked entry at the end */
- 			break;
- 		}
-+
-+		if (rx_limit-- < 2) {
-+			early_stop = 1;
-+			break;
-+		}
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+		processed++;
-+#endif
-+
- 		skb = bf->bf_skb;
- 		if (skb == NULL) {
- 			EPRINTF(sc, "Dropping; buffer contains NULL skbuff.\n");
-@@ -6450,6 +6537,7 @@ ath_rx_tasklet(TQUEUE_ARG data)
- 				sc->sc_stats.ast_rx_phyerr++;
- 				phyerr = rs->rs_phyerr & 0x1f;
- 				sc->sc_stats.ast_rx_phy[phyerr]++;
-+				goto rx_next;
- 			}
- 			if (rs->rs_status & HAL_RXERR_DECRYPT) {
- 				/*
-@@ -6645,9 +6733,39 @@ rx_next:
- 		STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
- 		ATH_RXBUF_UNLOCK_IRQ(sc);
- 	} while (ath_rxbuf_init(sc, bf) == 0);
-+	if (!early_stop) {
-+		unsigned long flags;
-+		/* Check if more data is received while we were
-+		 * processing the descriptor chain.
-+		 */
-+		local_irq_save(flags);
-+		if (sc->sc_isr & HAL_INT_RX) {
-+			u_int64_t hw_tsf = ath_hal_gettsf64(ah);
-+			sc->sc_isr &= ~HAL_INT_RX;
-+			local_irq_restore(flags);
-+			ath_uapsd_processtriggers(sc, hw_tsf);
-+			goto process_rx_again;
-+		}
-+		local_irq_restore(flags);
-+	}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+	netif_rx_complete(dev, napi);
-+#else
-+	netif_rx_complete(dev);
-+	*budget -= processed;
-+	dev->quota -= processed;
-+#endif
-+	sc->sc_imask |= HAL_INT_RX;
-+	ath_hal_intrset(ah, sc->sc_imask);
- 
- 	/* rx signal state monitoring */
- 	ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+	return processed;
-+#else
-+	return early_stop;
-+#endif
- #undef PA2DESC
- }
- 
-@@ -8298,12 +8416,24 @@ ath_tx_tasklet_q0(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *)data;
- 	struct ath_softc *sc = dev->priv;
-+	unsigned long flags;
- 
-+process_tx_again:
- 	if (txqactive(sc->sc_ah, 0))
- 		ath_tx_processq(sc, &sc->sc_txq[0]);
- 	if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
- 		ath_tx_processq(sc, sc->sc_cabq);
- 
-+	local_irq_save(flags);
-+	if (sc->sc_isr & HAL_INT_TX) {
-+		sc->sc_isr &= ~HAL_INT_TX;
-+		local_irq_restore(flags);
-+		goto process_tx_again;
-+	}
-+	sc->sc_imask |= HAL_INT_TX;
-+	ath_hal_intrset(sc->sc_ah, sc->sc_imask);
-+	local_irq_restore(flags);
-+
- 	netif_wake_queue(dev);
- 
- 	if (sc->sc_softled)
-@@ -8319,7 +8449,9 @@ ath_tx_tasklet_q0123(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *)data;
- 	struct ath_softc *sc = dev->priv;
-+	unsigned long flags;
- 
-+process_tx_again:
- 	/*
- 	 * Process each active queue.
- 	 */
-@@ -8340,6 +8472,16 @@ ath_tx_tasklet_q0123(TQUEUE_ARG data)
- 	if (sc->sc_uapsdq && txqactive(sc->sc_ah, sc->sc_uapsdq->axq_qnum))
- 		ath_tx_processq(sc, sc->sc_uapsdq);
- 
-+	local_irq_save(flags);
-+	if (sc->sc_isr & HAL_INT_TX) {
-+		sc->sc_isr &= ~HAL_INT_TX;
-+		local_irq_restore(flags);
-+		goto process_tx_again;
-+	}
-+	sc->sc_imask |= HAL_INT_TX;
-+	ath_hal_intrset(sc->sc_ah, sc->sc_imask);
-+	local_irq_restore(flags);
-+
- 	netif_wake_queue(dev);
- 
- 	if (sc->sc_softled)
-@@ -8355,13 +8497,25 @@ ath_tx_tasklet(TQUEUE_ARG data)
- 	struct net_device *dev = (struct net_device *)data;
- 	struct ath_softc *sc = dev->priv;
- 	unsigned int i;
-+	unsigned long flags;
- 
- 	/* Process each active queue. This includes sc_cabq, sc_xrtq and
- 	 * sc_uapsdq */
-+process_tx_again:
- 	for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
- 		if (ATH_TXQ_SETUP(sc, i) && txqactive(sc->sc_ah, i))
- 			ath_tx_processq(sc, &sc->sc_txq[i]);
- 
-+	local_irq_save(flags);
-+	if (sc->sc_isr & HAL_INT_TX) {
-+		sc->sc_isr &= ~HAL_INT_TX;
-+		local_irq_restore(flags);
-+		goto process_tx_again;
-+	}
-+	sc->sc_imask |= HAL_INT_TX;
-+	ath_hal_intrset(sc->sc_ah, sc->sc_imask);
-+	local_irq_restore(flags);
-+
- 	netif_wake_queue(dev);
- 
- 	if (sc->sc_softled)
-@@ -10296,9 +10450,9 @@ ath_change_mtu(struct net_device *dev, i
- 	dev->mtu = mtu;
- 	if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) {
- 		/* NB: the rx buffers may need to be reallocated */
--		tasklet_disable(&sc->sc_rxtq);
-+		ath_poll_disable(dev);
- 		error = ath_reset(dev);
--		tasklet_enable(&sc->sc_rxtq);
-+		ath_poll_enable(dev);
- 	}
- 	ATH_UNLOCK(sc);
- 
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -53,6 +53,10 @@
- # include	<asm/bitops.h>
- #endif
- 
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+#define irqs_disabled()			0
-+#endif
-+
- /*
-  * Deduce if tasklets are available.  If not then
-  * fall back to using the immediate work queue.
-@@ -616,6 +620,9 @@ struct ath_rp {
- struct ath_softc {
- 	struct ieee80211com sc_ic;		/* NB: must be first */
- 	struct net_device *sc_dev;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+	struct napi_struct sc_napi;
-+#endif
- 	void __iomem *sc_iobase;		/* address of the device */
- 	struct semaphore sc_lock;		/* dev-level lock */
- 	struct net_device_stats	sc_devstats;	/* device statistics */
-@@ -730,7 +737,6 @@ struct ath_softc {
- 	struct ath_buf *sc_rxbufcur;		/* current rx buffer */
- 	u_int32_t *sc_rxlink;			/* link ptr in last RX desc */
- 	spinlock_t sc_rxbuflock;
--	struct ATH_TQ_STRUCT sc_rxtq;		/* rx intr tasklet */
- 	struct ATH_TQ_STRUCT sc_rxorntq;	/* rxorn intr tasklet */
- 	u_int8_t sc_defant;			/* current default antenna */
- 	u_int8_t sc_rxotherant;			/* RXs on non-default antenna */
-@@ -745,6 +751,7 @@ struct ath_softc {
- 	u_int sc_txintrperiod;			/* tx interrupt batching */
- 	struct ath_txq sc_txq[HAL_NUM_TX_QUEUES];
- 	struct ath_txq *sc_ac2q[WME_NUM_AC];	/* WME AC -> h/w qnum */
-+	HAL_INT sc_isr;				/* unmasked ISR state */
- 	struct ATH_TQ_STRUCT sc_txtq;		/* tx intr tasklet */
- 	u_int8_t sc_grppoll_str[GRPPOLL_RATE_STR_LEN];
- 	struct ath_descdma sc_bdma;		/* beacon descriptors */
-@@ -858,6 +865,8 @@ typedef void (*ath_callback) (struct ath
- #define	ATH_TXBUF_LOCK_CHECK(_sc)
- #endif
- 
-+#define ATH_DISABLE_INTR		local_irq_disable
-+#define ATH_ENABLE_INTR 		local_irq_enable
- 
- #define	ATH_RXBUF_LOCK_INIT(_sc)	spin_lock_init(&(_sc)->sc_rxbuflock)
- #define	ATH_RXBUF_LOCK_DESTROY(_sc)
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -1198,7 +1198,7 @@ ieee80211_deliver_data(struct ieee80211_
- 			/* attach vlan tag */
- 			struct ieee80211_node *ni_tmp = SKB_CB(skb)->ni;
- 			if (vlan_hwaccel_receive_skb(skb, vap->iv_vlgrp, ni->ni_vlan) == NET_RX_DROP) {
--				/* If netif_rx dropped the packet because 
-+				/* If netif_receive_skb dropped the packet because
- 				 * device was too busy */
- 				if (ni_tmp != NULL) {
- 					/* node reference was leaked */
-@@ -1209,8 +1209,8 @@ ieee80211_deliver_data(struct ieee80211_
- 			skb = NULL; /* SKB is no longer ours */
- 		} else {
- 			struct ieee80211_node *ni_tmp = SKB_CB(skb)->ni;
--			if (netif_rx(skb) == NET_RX_DROP) {
--				/* If netif_rx dropped the packet because 
-+			if (netif_receive_skb(skb) == NET_RX_DROP) {
-+				/* If netif_receive_skb dropped the packet because
- 				 * device was too busy */
- 				if (ni_tmp != NULL) {
- 					/* node reference was leaked */
-@@ -2322,8 +2322,8 @@ forward_mgmt_to_app(struct ieee80211vap
- 		skb1->protocol = __constant_htons(0x0019);  /* ETH_P_80211_RAW */
- 
- 		ni_tmp = SKB_CB(skb1)->ni;
--		if (netif_rx(skb1) == NET_RX_DROP) {
--			/* If netif_rx dropped the packet because 
-+		if (netif_receive_skb(skb1) == NET_RX_DROP) {
-+			/* If netif_receive_skb dropped the packet because
- 			 * device was too busy */
- 			if (ni_tmp != NULL) {
- 				/* node reference was leaked */
---- a/net80211/ieee80211_monitor.c
-+++ b/net80211/ieee80211_monitor.c
-@@ -584,8 +584,8 @@ ieee80211_input_monitor(struct ieee80211
- 			skb1->protocol = 
- 				__constant_htons(0x0019); /* ETH_P_80211_RAW */
- 
--			if (netif_rx(skb1) == NET_RX_DROP) {
--				/* If netif_rx dropped the packet because 
-+			if (netif_receive_skb(skb1) == NET_RX_DROP) {
-+				/* If netif_receive_skb dropped the packet because
- 				 * device was too busy, reclaim the ref. in 
- 				 * the skb. */
- 				if (SKB_CB(skb1)->ni != NULL)
---- a/net80211/ieee80211_skb.c
-+++ b/net80211/ieee80211_skb.c
-@@ -73,7 +73,7 @@
- #undef dev_queue_xmit
- #undef kfree_skb
- #undef kfree_skb_fast
--#undef netif_rx
-+#undef netif_receive_skb
- #undef pskb_copy
- #undef skb_clone
- #undef skb_copy
-@@ -638,8 +638,8 @@ int  vlan_hwaccel_receive_skb_debug(stru
- 		grp, vlan_tag);
- }
- 
--int netif_rx_debug(struct sk_buff *skb, const char* func, int line) {
--	return netif_rx(untrack_skb(skb, 0, func, line, __func__, __LINE__));
-+int netif_receive_skb_debug(struct sk_buff *skb, const char* func, int line) {
-+	return netif_receive_skb(untrack_skb(skb, 0, func, line, __func__, __LINE__));
- }
- 
- struct sk_buff * alloc_skb_debug(unsigned int length, gfp_t gfp_mask,
-@@ -760,7 +760,7 @@ struct sk_buff * skb_copy_expand_debug(c
- }
- 
- EXPORT_SYMBOL(vlan_hwaccel_receive_skb_debug);
--EXPORT_SYMBOL(netif_rx_debug);
-+EXPORT_SYMBOL(netif_receive_skb_debug);
- EXPORT_SYMBOL(alloc_skb_debug);
- EXPORT_SYMBOL(dev_alloc_skb_debug);
- EXPORT_SYMBOL(skb_clone_debug);
---- a/net80211/ieee80211_skb.h
-+++ b/net80211/ieee80211_skb.h
-@@ -116,7 +116,7 @@ int ieee80211_skb_references(void);
- int  vlan_hwaccel_receive_skb_debug(struct sk_buff *skb, 
- 				    struct vlan_group *grp, unsigned short vlan_tag, 
- 				    const char* func, int line);
--int netif_rx_debug(struct sk_buff *skb, const char* func, int line);
-+int netif_receive_skb_debug(struct sk_buff *skb, const char* func, int line);
- struct sk_buff * alloc_skb_debug(unsigned int length, gfp_t gfp_mask,
- 				 const char *func, int line);
- struct sk_buff * dev_alloc_skb_debug(unsigned int length,
-@@ -151,7 +151,7 @@ struct sk_buff * skb_copy_expand_debug(c
- #undef dev_queue_xmit
- #undef kfree_skb
- #undef kfree_skb_fast
--#undef netif_rx
-+#undef netif_receive_skb
- #undef pskb_copy
- #undef skb_clone
- #undef skb_copy
-@@ -168,8 +168,8 @@ struct sk_buff * skb_copy_expand_debug(c
- 	skb_copy_expand_debug(_skb, _newheadroom, _newtailroom, _gfp_mask, __func__, __LINE__)
- #define vlan_hwaccel_receive_skb(_skb, _grp, _tag) \
- 	vlan_hwaccel_receive_skb_debug(_skb, _grp, _tag, __func__, __LINE__)
--#define netif_rx(_skb) \
--	netif_rx_debug(_skb, __func__, __LINE__)
-+#define netif_receive_skb(_skb) \
-+	netif_receive_skb_debug(_skb, __func__, __LINE__)
- #define	alloc_skb(_length, _gfp_mask) \
- 	alloc_skb_debug(_length, _gfp_mask, __func__, __LINE__)
- #define	dev_alloc_skb(_length) \
diff --git a/package/madwifi/patches/305-pureg_fix.patch b/package/madwifi/patches/305-pureg_fix.patch
deleted file mode 100644
index 8adb8a7162..0000000000
--- a/package/madwifi/patches/305-pureg_fix.patch
+++ /dev/null
@@ -1,168 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -4158,7 +4158,9 @@ ath_calcrxfilter(struct ath_softc *sc)
- 		rfilt |= HAL_RX_FILTER_PROM;
- 	if (ic->ic_opmode == IEEE80211_M_STA ||
- 	    sc->sc_opmode == HAL_M_IBSS ||	/* NB: AHDEMO too */
--	    (sc->sc_nostabeacons) || sc->sc_scanning)
-+	    (sc->sc_nostabeacons) || sc->sc_scanning ||
-+		((ic->ic_opmode == IEEE80211_M_HOSTAP) &&
-+		 (ic->ic_protmode != IEEE80211_PROT_NONE)))
- 		rfilt |= HAL_RX_FILTER_BEACON;
- 	if (sc->sc_nmonvaps > 0)
- 		rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -346,11 +346,12 @@ ieee80211_input(struct ieee80211vap * va
- 				bssid = wh->i_addr3;
- 			}
- 			/*
--			 * Validate the bssid.
-+			 * Validate the bssid. Let beacons get through though for 11g protection mode.
- 			 */
--#ifdef ATH_SUPERG_XR
- 			if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) &&
--			    !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) {
-+			    !IEEE80211_ADDR_EQ(bssid, dev->broadcast) &&
-+				(subtype != IEEE80211_FC0_SUBTYPE_BEACON)) {
-+#ifdef ATH_SUPERG_XR
- 				/*
- 				 * allow MGT frames to vap->iv_xrvap.
- 				 * this will allow roaming between  XR and normal vaps
-@@ -366,18 +367,14 @@ ieee80211_input(struct ieee80211vap * va
- 					vap->iv_stats.is_rx_wrongbss++;
- 					goto out;
- 				}
--			}
- #else
--			if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) &&
--			    !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) {
- 				/* not interested in */
- 				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
- 					bssid, NULL, "%s", "not to bss");
- 				vap->iv_stats.is_rx_wrongbss++;
- 				goto out;
--			}
--
- #endif
-+			}
- 			break;
- 		case IEEE80211_M_WDS:
- 			if (skb->len < sizeof(struct ieee80211_frame_addr4)) {
-@@ -3066,7 +3063,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 	u_int8_t *frm, *efrm;
- 	u_int8_t *ssid, *rates, *xrates, *suppchan, *wpa, *rsn, *wme, *ath;
- 	u_int8_t rate;
--	int reassoc, resp, allocbs = 0;
-+	int reassoc, resp, allocbs = 0, has_erp = 0;
- 	u_int8_t qosinfo;
- 
- 	if (ni_or_null == NULL)
-@@ -3096,11 +3093,15 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 		 *    o station mode when associated (to collect state
- 		 *      updates such as 802.11g slot time), or
- 		 *    o adhoc mode (to discover neighbors)
-+		 *    o ap mode in protection mode (beacons only)
- 		 * Frames otherwise received are discarded.
- 		 */
- 		if (!((ic->ic_flags & IEEE80211_F_SCAN) ||
- 		    (vap->iv_opmode == IEEE80211_M_STA && ni->ni_associd) ||
--		    vap->iv_opmode == IEEE80211_M_IBSS)) {
-+		    (vap->iv_opmode == IEEE80211_M_IBSS) ||
-+			((subtype == IEEE80211_FC0_SUBTYPE_BEACON) &&
-+			 (vap->iv_opmode == IEEE80211_M_HOSTAP) &&
-+			 (ic->ic_protmode != IEEE80211_PROT_NONE)))) {
- 			vap->iv_stats.is_rx_mgtdiscard++;
- 			return;
- 		}
-@@ -3184,6 +3185,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 					break;
- 				}
- 				scan.erp = frm[2];
-+				has_erp = 1;
- 				break;
- 			case IEEE80211_ELEMID_RSN:
- 				scan.rsn = frm;
-@@ -3421,6 +3423,20 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 				ieee80211_bg_scan(vap);
- 			return;
- 		}
-+
-+		/* Update AP protection mode when in 11G mode */
-+		if ((vap->iv_opmode == IEEE80211_M_HOSTAP) &&
-+			IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
-+
-+			/* Assume no ERP IE == 11b AP */
-+			if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
-+				!(ic->ic_flags & IEEE80211_F_USEPROT)) {
-+
-+				ic->ic_flags |= IEEE80211_F_USEPROT;
-+				ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+			}
-+		}
-+
- 		/*
- 		 * If scanning, just pass information to the scan module.
- 		 */
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -383,10 +383,16 @@ ieee80211_create_ibss(struct ieee80211va
- 	/* Update country ie information */
- 	ieee80211_build_countryie(ic);
- 
--	if (IEEE80211_IS_CHAN_HALF(chan))
-+	if (IEEE80211_IS_CHAN_HALF(chan)) {
- 		ni->ni_rates = ic->ic_sup_half_rates;
--	else if (IEEE80211_IS_CHAN_QUARTER(chan))
-+	} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
- 		ni->ni_rates = ic->ic_sup_quarter_rates;
-+	}
-+
-+	if ((vap->iv_flags & IEEE80211_F_PUREG) &&
-+		IEEE80211_IS_CHAN_ANYG(chan)) {
-+		ieee80211_setpuregbasicrates(&ni->ni_rates);
-+	}
- 
- 	(void) ieee80211_sta_join1(PASS_NODE(ni));
- }
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -595,6 +595,28 @@ static const struct ieee80211_rateset ba
- 	{ 4, { 2, 4, 11, 22 } },	/* IEEE80211_MODE_TURBO_G (mixed b/g) */
- };
- 
-+static const struct ieee80211_rateset basicpureg[] = {
-+    { 7, {2, 4, 11, 22, 12, 24, 48 } },
-+};
-+
-+/*
-+ * Mark basic rates for the 11g rate table based on the pureg setting
-+ */
-+void
-+ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs)
-+{
-+	int i, j;
-+
-+	for (i = 0; i < rs->rs_nrates; i++) {
-+		rs->rs_rates[i] &= IEEE80211_RATE_VAL;
-+		for (j = 0; j < basicpureg[0].rs_nrates; j++)
-+			if (basicpureg[0].rs_rates[j] == rs->rs_rates[i]) {
-+				rs->rs_rates[i] |= IEEE80211_RATE_BASIC;
-+				break;
-+			}
-+	}
-+}
-+
- /*
-  * Mark the basic rates for the 11g rate table based on the
-  * specified mode.  For 11b compatibility we mark only 11b
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -708,6 +708,7 @@ int ieee80211_media_setup(struct ieee802
- void ieee80211_build_sc_ie(struct ieee80211com *);
- void ieee80211_dfs_action(struct ieee80211com *);
- void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *);
-+void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs);
- 
- /*
-  * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers.
diff --git a/package/madwifi/patches/309-micfail_detect.patch b/package/madwifi/patches/309-micfail_detect.patch
deleted file mode 100644
index ca4103a206..0000000000
--- a/package/madwifi/patches/309-micfail_detect.patch
+++ /dev/null
@@ -1,321 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -6457,6 +6457,7 @@ ath_rx_poll(struct net_device *dev, int
- 	int type;
- 	u_int phyerr;
- 	u_int processed = 0, early_stop = 0;
-+	u_int mic_fail = 0;
- 
- 	DPRINTF(sc, ATH_DEBUG_RX_PROC, "invoked\n");
- process_rx_again:
-@@ -6558,24 +6559,8 @@ process_rx_again:
- 			}
- 			if (rs->rs_status & HAL_RXERR_MIC) {
- 				sc->sc_stats.ast_rx_badmic++;
--				/*
--				 * Do minimal work required to hand off
--				 * the 802.11 header for notification.
--				 */
--				/* XXX frag's and QoS frames */
--				if (len >= sizeof (struct ieee80211_frame)) {
--					bus_dma_sync_single(sc->sc_bdev,
--					    bf->bf_skbaddr, len,
--					    BUS_DMA_FROMDEVICE);
--#if 0
--/* XXX revalidate MIC, lookup ni to find VAP */
--					ieee80211_notify_michael_failure(ic,
--					    (struct ieee80211_frame *)skb->data,
--					    sc->sc_splitmic ?
--					        rs->rs_keyix - 32 : rs->rs_keyix
--					);
--#endif
--				}
-+				mic_fail = 1;
-+				goto rx_accept;
- 			}
- 			/*
- 			 * Reject error frames if we have no vaps that
-@@ -6614,8 +6599,9 @@ rx_accept:
- 		/*
- 		 * Finished monitor mode handling, now reject
- 		 * error frames before passing to other vaps
-+		 * Ignore MIC failures here, as we need to recheck them
- 		 */
--		if (rs->rs_status != 0) {
-+		if (rs->rs_status & ~(HAL_RXERR_MIC | HAL_RXERR_DECRYPT)) {
- 			ieee80211_dev_kfree_skb(&skb);
- 			goto rx_next;
- 		}
-@@ -6623,6 +6609,26 @@ rx_accept:
- 		/* remove the CRC */
- 		skb_trim(skb, skb->len - IEEE80211_CRC_LEN);
- 
-+		if (mic_fail) {
-+			/* Ignore control frames which are reported with mic error */
-+		    if ((((struct ieee80211_frame *)skb->data)->i_fc[0] &
-+					IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
-+				goto drop_micfail;
-+
-+			ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
-+
-+			if (ni && ni->ni_table) {
-+				ieee80211_check_mic(ni, skb);
-+				ieee80211_unref_node(&ni);
-+			}
-+
-+drop_micfail:
-+			dev_kfree_skb_any(skb);
-+			skb = NULL;
-+			mic_fail = 0;
-+			goto rx_next;
-+		}
-+
- 		/*
- 		 * From this point on we assume the frame is at least
- 		 * as large as ieee80211_frame_min; verify that.
-@@ -6635,6 +6641,7 @@ rx_accept:
- 			goto rx_next;
- 		}
- 
-+		/* MIC failure. Drop the packet in any case */
- 		/*
- 		 * Normal receive.
- 		 */
---- a/net80211/ieee80211_crypto_ccmp.c
-+++ b/net80211/ieee80211_crypto_ccmp.c
-@@ -73,7 +73,7 @@ static int ccmp_setkey(struct ieee80211_
- static int ccmp_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
- static int ccmp_decap(struct ieee80211_key *, struct sk_buff *, int);
- static int ccmp_enmic(struct ieee80211_key *, struct sk_buff *, int);
--static int ccmp_demic(struct ieee80211_key *, struct sk_buff *, int);
-+static int ccmp_demic(struct ieee80211_key *, struct sk_buff *, int, int);
- 
- static const struct ieee80211_cipher ccmp = {
- 	.ic_name	= "AES-CCM",
-@@ -314,7 +314,7 @@ ccmp_decap(struct ieee80211_key *k, stru
-  * Verify and strip MIC from the frame.
-  */
- static int
--ccmp_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen)
-+ccmp_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen, int force)
- {
- 	return 1;
- }
---- a/net80211/ieee80211_crypto.h
-+++ b/net80211/ieee80211_crypto.h
-@@ -145,7 +145,7 @@ struct ieee80211_cipher {
- 	int (*ic_encap)(struct ieee80211_key *, struct sk_buff *, u_int8_t);
- 	int (*ic_decap)(struct ieee80211_key *, struct sk_buff *, int);
- 	int (*ic_enmic)(struct ieee80211_key *, struct sk_buff *, int);
--	int (*ic_demic)(struct ieee80211_key *, struct sk_buff *, int);
-+	int (*ic_demic)(struct ieee80211_key *, struct sk_buff *, int, int);
- };
- extern const struct ieee80211_cipher ieee80211_cipher_none;
- 
-@@ -163,10 +163,10 @@ struct ieee80211_key *ieee80211_crypto_d
-  */
- static __inline int
- ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
--	struct sk_buff *skb, int hdrlen)
-+	struct sk_buff *skb, int hdrlen, int force)
- {
- 	const struct ieee80211_cipher *cip = k->wk_cipher;
--	return (cip->ic_miclen > 0 ? cip->ic_demic(k, skb, hdrlen) : 1);
-+	return (cip->ic_miclen > 0 ? cip->ic_demic(k, skb, hdrlen, force) : 1);
- }
- 
- /*
---- a/net80211/ieee80211_crypto_none.c
-+++ b/net80211/ieee80211_crypto_none.c
-@@ -52,7 +52,7 @@ static int none_setkey(struct ieee80211_
- static int none_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
- static int none_decap(struct ieee80211_key *, struct sk_buff *, int);
- static int none_enmic(struct ieee80211_key *, struct sk_buff *, int);
--static int none_demic(struct ieee80211_key *, struct sk_buff *, int);
-+static int none_demic(struct ieee80211_key *, struct sk_buff *, int, int);
- 
- const struct ieee80211_cipher ieee80211_cipher_none = {
- 	.ic_name	= "NONE",
-@@ -137,7 +137,7 @@ none_enmic(struct ieee80211_key *k, stru
- }
- 
- static int
--none_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen)
-+none_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen, int force)
- {
- 	struct ieee80211vap *vap = k->wk_private;
- 
---- a/net80211/ieee80211_crypto_tkip.c
-+++ b/net80211/ieee80211_crypto_tkip.c
-@@ -57,7 +57,7 @@ static int tkip_setkey(struct ieee80211_
- static int tkip_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
- static int tkip_enmic(struct ieee80211_key *, struct sk_buff *, int);
- static int tkip_decap(struct ieee80211_key *, struct sk_buff *, int);
--static int tkip_demic(struct ieee80211_key *, struct sk_buff *, int);
-+static int tkip_demic(struct ieee80211_key *, struct sk_buff *, int, int);
- 
- static const struct ieee80211_cipher tkip  = {
- 	.ic_name	= "TKIP",
-@@ -339,7 +339,7 @@ tkip_decap(struct ieee80211_key *k, stru
-  * Verify and strip MIC from the frame.
-  */
- static int
--tkip_demic(struct ieee80211_key *k, struct sk_buff *skb0, int hdrlen)
-+tkip_demic(struct ieee80211_key *k, struct sk_buff *skb0, int hdrlen, int force)
- {
- 	struct tkip_ctx *ctx = k->wk_private;
- 	struct sk_buff *skb;
-@@ -355,7 +355,7 @@ tkip_demic(struct ieee80211_key *k, stru
- 	}
- 	wh = (struct ieee80211_frame *) skb0->data;
- 	/* NB: skb left pointing at last in chain */
--	if (k->wk_flags & IEEE80211_KEY_SWMIC) {
-+	if ((k->wk_flags & IEEE80211_KEY_SWMIC) || force) {
- 		struct ieee80211vap *vap = ctx->tc_vap;
- 		u8 mic[IEEE80211_WEP_MICLEN];
- 		u8 mic0[IEEE80211_WEP_MICLEN];
---- a/net80211/ieee80211_crypto_wep.c
-+++ b/net80211/ieee80211_crypto_wep.c
-@@ -54,7 +54,7 @@ static int wep_setkey(struct ieee80211_k
- static int wep_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
- static int wep_decap(struct ieee80211_key *, struct sk_buff *, int);
- static int wep_enmic(struct ieee80211_key *, struct sk_buff *, int);
--static int wep_demic(struct ieee80211_key *, struct sk_buff *, int);
-+static int wep_demic(struct ieee80211_key *, struct sk_buff *, int, int);
- 
- static const struct ieee80211_cipher wep = {
- 	.ic_name	= "WEP",
-@@ -244,7 +244,7 @@ wep_decap(struct ieee80211_key *k, struc
-  * Verify and strip MIC from the frame.
-  */
- static int
--wep_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen)
-+wep_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen, int force)
- {
- 	return 1;
- }
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -669,7 +669,7 @@ ieee80211_input(struct ieee80211vap * va
- 		 * Next strip any MSDU crypto bits.
- 		 */
- 		if (key != NULL &&
--		    !ieee80211_crypto_demic(vap, key, skb, hdrspace)) {
-+		    !ieee80211_crypto_demic(vap, key, skb, hdrspace, 0)) {
- 			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
- 				ni->ni_macaddr, "data", "%s", "demic error");
- 			IEEE80211_NODE_STAT(ni, rx_demicfail);
-@@ -4293,6 +4293,47 @@ ath_eth_type_trans(struct sk_buff *skb,
- }
- #endif
- 
-+/*
-+ * Process a frame w/ hw detected MIC failure.
-+ * The frame will be dropped in any case.
-+ */
-+void
-+ieee80211_check_mic(struct ieee80211_node *ni, struct sk_buff *skb)
-+{
-+	struct ieee80211vap *vap = ni->ni_vap;
-+
-+	struct ieee80211_frame *wh;
-+	struct ieee80211_key *key;
-+	int hdrspace;
-+	struct ieee80211com *ic = vap->iv_ic;
-+
-+	if (skb->len < sizeof(struct ieee80211_frame_min)) {
-+		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
-+		    ni->ni_macaddr, NULL,
-+		    "too short (1): len %u", skb->len);
-+		vap->iv_stats.is_rx_tooshort++;
-+		return;
-+	}
-+
-+	wh = (struct ieee80211_frame *)skb->data;
-+
-+	hdrspace = ieee80211_hdrspace(ic, wh);
-+	key = ieee80211_crypto_decap(ni, skb, hdrspace);
-+	if (key == NULL) {
-+		/* NB: stats+msgs handled in crypto_decap */
-+		IEEE80211_NODE_STAT(ni, rx_wepfail);
-+		return;
-+	}
-+
-+	if (!ieee80211_crypto_demic(vap, key, skb, hdrspace, 1)) {
-+		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
-+			ni->ni_macaddr, "data", "%s", "demic error");
-+			IEEE80211_NODE_STAT(ni, rx_demicfail);
-+	}
-+	return;
-+}
-+EXPORT_SYMBOL(ieee80211_check_mic);
-+
- #ifdef IEEE80211_DEBUG
- /*
-  * Debugging support.
---- a/net80211/ieee80211_proto.h
-+++ b/net80211/ieee80211_proto.h
-@@ -90,6 +90,7 @@ int ieee80211_iserp_rateset(struct ieee8
- void ieee80211_set11gbasicrates(struct ieee80211_rateset *, enum ieee80211_phymode);
- enum ieee80211_phymode ieee80211_get11gbasicrates(struct ieee80211_rateset *);
- void ieee80211_send_pspoll(struct ieee80211_node *);
-+void ieee80211_check_mic(struct ieee80211_node *, struct sk_buff *);
- 
- /*
-  * Return the size of the 802.11 header for a management or data frame.
---- a/net80211/ieee80211_linux.c
-+++ b/net80211/ieee80211_linux.c
-@@ -337,8 +337,8 @@ ieee80211_notify_replay_failure(struct i
- 	/* TODO: needed parameters: count, keyid, key type, src address, TSC */
- 	snprintf(buf, sizeof(buf), "%s(keyid=%d %scast addr=" MAC_FMT ")", tag,
- 		k->wk_keyix,
--		IEEE80211_IS_MULTICAST(wh->i_addr1) ?  "broad" : "uni",
--		MAC_ADDR(wh->i_addr1));
-+		IEEE80211_IS_MULTICAST(wh->i_addr2) ?  "broad" : "uni",
-+		MAC_ADDR(wh->i_addr2));
- 	memset(&wrqu, 0, sizeof(wrqu));
- 	wrqu.data.length = strlen(buf);
- 	wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -1074,13 +1074,16 @@ ieee80211_encap(struct ieee80211_node *n
- 			cip = (struct ieee80211_cipher *) key->wk_cipher;
- 			ciphdrsize = cip->ic_header;
- 			tailsize += (cip->ic_trailer + cip->ic_miclen);
-+
-+			/* add the 8 bytes MIC length */
-+			if (cip->ic_cipher == IEEE80211_CIPHER_TKIP)
-+				pktlen += IEEE80211_WEP_MICLEN;
- 		}
- 
- 		pdusize = vap->iv_fragthreshold - (hdrsize_nopad + ciphdrsize);
- 		fragcnt = *framecnt =
--			((pktlen - (hdrsize_nopad + ciphdrsize)) / pdusize) +
--			(((pktlen - (hdrsize_nopad + ciphdrsize)) %
--				pdusize == 0) ? 0 : 1);
-+			((pktlen - hdrsize_nopad) / pdusize) +
-+			(((pktlen - hdrsize_nopad) % pdusize == 0) ? 0 : 1);
- 
- 		/*
- 		 * Allocate sk_buff for each subsequent fragment; First fragment
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -2264,11 +2264,13 @@ ieee80211_node_leave(struct ieee80211_no
- 	/* From this point onwards we can no longer find the node,
- 	 * so no more references are generated
- 	 */
--	ieee80211_remove_wds_addr(nt, ni->ni_macaddr);
--	ieee80211_del_wds_node(nt, ni);
--	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
--	node_table_leave_locked(nt, ni);
--	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
-+	if (nt) {
-+		ieee80211_remove_wds_addr(nt, ni->ni_macaddr);
-+		ieee80211_del_wds_node(nt, ni);
-+		IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
-+		node_table_leave_locked(nt, ni);
-+		IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
-+	}
- 
- 	/*
- 	 * If node wasn't previously associated all
diff --git a/package/madwifi/patches/310-noise_get.patch b/package/madwifi/patches/310-noise_get.patch
deleted file mode 100644
index d8821583b3..0000000000
--- a/package/madwifi/patches/310-noise_get.patch
+++ /dev/null
@@ -1,55 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -1699,8 +1699,6 @@ ath_uapsd_processtriggers(struct ath_sof
- 	 * get to reality.  This value is used in monitor mode and by tools like
- 	 * Wireshark and Kismet.
- 	 */
--	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
--
- 	ATH_RXBUF_LOCK_IRQ(sc);
- 	if (sc->sc_rxbufcur == NULL)
- 		sc->sc_rxbufcur = STAILQ_FIRST(&sc->sc_rxbuf);
-@@ -8975,6 +8973,7 @@ ath_calibrate(unsigned long arg)
- 			sc->sc_curchan.channel);
- 		sc->sc_stats.ast_per_calfail++;
- 	}
-+	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
- 
- 	ath_hal_process_noisefloor(ah);
- 	if (isIQdone == AH_TRUE) {
-@@ -9043,6 +9042,7 @@ ath_set_channel(struct ieee80211com *ic)
- 	struct ath_softc *sc = dev->priv;
- 
- 	(void) ath_chan_set(sc, ic->ic_curchan);
-+	ic->ic_channoise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan));
- 	/*
- 	 * If we are returning to our bss channel then mark state
- 	 * so the next recv'd beacon's TSF will be used to sync the
-@@ -9311,6 +9311,7 @@ ath_newstate(struct ieee80211vap *vap, e
- 		}
- 
- 		ath_hal_process_noisefloor(ah);
-+		ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
- 		/*
- 		 * Reset rssi stats; maybe not the best place...
- 		 */
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -4358,6 +4358,7 @@ get_sta_info(void *arg, struct ieee80211
- 	si->isi_state = ni->ni_flags;
- 	si->isi_authmode = ni->ni_authmode;
- 	si->isi_rssi = ic->ic_node_getrssi(ni);
-+	si->isi_noise = ic->ic_channoise;
- 	si->isi_capinfo = ni->ni_capinfo;
- 	si->isi_athflags = ni->ni_ath_flags;
- 	si->isi_erp = ni->ni_erp;
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -311,6 +311,7 @@ struct ieee80211req_sta_info {
- 	u_int16_t isi_state;		/* state flags */
- 	u_int8_t isi_authmode;		/* authentication algorithm */
- 	u_int8_t isi_rssi;
-+	int8_t isi_noise;
- 	u_int16_t isi_capinfo;		/* capabilities */
- 	u_int8_t isi_athflags;		/* Atheros capabilities */
- 	u_int8_t isi_erp;		/* ERP element */
diff --git a/package/madwifi/patches/311-bssid_alloc.patch b/package/madwifi/patches/311-bssid_alloc.patch
deleted file mode 100644
index 005a67738c..0000000000
--- a/package/madwifi/patches/311-bssid_alloc.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -1354,7 +1354,7 @@ ath_vap_create(struct ieee80211com *ic,
- 		TAILQ_FOREACH(v, &ic->ic_vaps, iv_next)
- 			id_mask |= (1 << ATH_GET_VAP_ID(v->iv_myaddr));
- 
--		for (id = 1; id < ath_maxvaps; id++) {
-+		for (id = 0; id < ath_maxvaps; id++) {
- 			/* get the first available slot */
- 			if ((id_mask & (1 << id)) == 0) {
- 				ATH_SET_VAP_BSSID(vap->iv_myaddr, id);
diff --git a/package/madwifi/patches/312-erpupdate.patch b/package/madwifi/patches/312-erpupdate.patch
deleted file mode 100644
index f878acd8f4..0000000000
--- a/package/madwifi/patches/312-erpupdate.patch
+++ /dev/null
@@ -1,68 +0,0 @@
---- a/net80211/ieee80211_beacon.c
-+++ b/net80211/ieee80211_beacon.c
-@@ -542,10 +542,10 @@ ieee80211_beacon_update(struct ieee80211
- 			vap->iv_flags &= ~IEEE80211_F_XRUPDATE;
- 		}
- #endif
--		if ((ic->ic_flags_ext & IEEE80211_FEXT_ERPUPDATE) && 
-+		if ((vap->iv_flags_ext & IEEE80211_FEXT_ERPUPDATE) &&
- 				(bo->bo_erp != NULL)) {
- 			(void)ieee80211_add_erp(bo->bo_erp, ic);
--			ic->ic_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE;
-+			vap->iv_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE;
- 		}
- 	}
- 	/* if it is a mode change beacon for dynamic turbo case */
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -3431,9 +3431,12 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			/* Assume no ERP IE == 11b AP */
- 			if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
- 				!(ic->ic_flags & IEEE80211_F_USEPROT)) {
-+				struct ieee80211vap *tmpvap;
- 
- 				ic->ic_flags |= IEEE80211_F_USEPROT;
--				ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+				TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
-+					tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+				}
- 			}
- 		}
- 
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -2025,8 +2025,12 @@ ieee80211_node_join_11g(struct ieee80211
- 		}
- 
- 		/* Update ERP element if this is first non ERP station */
--		if (ic->ic_nonerpsta == 1)
--			ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+		if (ic->ic_nonerpsta == 1) {
-+			struct ieee80211vap *tmpvap;
-+			TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
-+				tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+			}
-+		}
- 	} else
- 		ni->ni_flags |= IEEE80211_NODE_ERP;
- }
-@@ -2229,6 +2233,8 @@ ieee80211_node_leave_11g(struct ieee8021
- 		IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
- 			"non-ERP station leaves, count now %d", ic->ic_nonerpsta);
- 		if (ic->ic_nonerpsta == 0) {
-+			struct ieee80211vap *tmpvap;
-+
- 			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
- 				"%s: disable use of protection\n", __func__);
- 			ic->ic_flags &= ~IEEE80211_F_USEPROT;
-@@ -2240,7 +2246,9 @@ ieee80211_node_leave_11g(struct ieee8021
- 				ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
- 				ic->ic_flags &= ~IEEE80211_F_USEBARKER;
- 			}
--			ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+			TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
-+				tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+			}
- 		}
- 	}
- }
diff --git a/package/madwifi/patches/317-bmask.patch b/package/madwifi/patches/317-bmask.patch
deleted file mode 100644
index 3355dc7221..0000000000
--- a/package/madwifi/patches/317-bmask.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -8689,6 +8689,10 @@ ath_startrecv(struct ath_softc *sc)
- 
- 	sc->sc_rxbufcur = NULL;
- 
-+	/* configure bssid mask */
-+	if (sc->sc_hasbmask)
-+		ath_hal_setbssidmask(ah, sc->sc_bssidmask);
-+
- 	bf = STAILQ_FIRST(&sc->sc_rxbuf);
- 	ath_hal_putrxbuf(ah, bf->bf_daddr);
- 	ath_hal_rxena(ah);		/* enable recv descriptors */
diff --git a/package/madwifi/patches/323-dfs_optional.patch b/package/madwifi/patches/323-dfs_optional.patch
deleted file mode 100644
index 2336d7484e..0000000000
--- a/package/madwifi/patches/323-dfs_optional.patch
+++ /dev/null
@@ -1,38 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -1778,17 +1778,14 @@ ath_uapsd_processtriggers(struct ath_sof
- 			 * may have occurred in the intervening timeframe. */
- 			bf->bf_channoise = ic->ic_channoise;
- 
--			if (rs->rs_status) {
--				if ((HAL_RXERR_PHY == rs->rs_status) &&
--				    (HAL_PHYERR_RADAR ==
--				     (rs->rs_phyerr & 0x1f)) &&
--				    (0 == (bf->bf_status &
--					   ATH_BUFSTATUS_RADAR_DONE))) {
--					check_for_radar = 1;
--				}
--				/* Skip past the error now */
-+			if ((HAL_RXERR_PHY == rs->rs_status) &&
-+			    (HAL_PHYERR_RADAR == (rs->rs_phyerr & 0x1f)) &&
-+			    (0 == (bf->bf_status & ATH_BUFSTATUS_RADAR_DONE)) &&
-+			    (ic->ic_flags & IEEE80211_F_DOTH))
-+				check_for_radar = 1;
-+
-+			if (rs->rs_status) /* Skip past the error now */
- 				continue;
--			}
- 
- 			/* Prepare wireless header for examination */
- 			bus_dma_sync_single(sc->sc_bdev, bf->bf_skbaddr,
---- a/ath/if_ath_radar.c
-+++ b/ath/if_ath_radar.c
-@@ -265,7 +265,7 @@ int ath_radar_update(struct ath_softc *s
- 		unsigned int new_rxfilt = old_rxfilt;
- 
- 		ath_hal_intrset(ah, old_ier & ~HAL_INT_GLOBAL);
--		if (required) {
-+		if ((required) && (ic->ic_flags & IEEE80211_F_DOTH)) {
- 			new_radar |= AR5K_PHY_RADAR_ENABLE;
- 			new_filter |= AR5K_AR5212_PHY_ERR_FIL_RADAR;
- 			new_rxfilt |= (HAL_RX_FILTER_PHYERR | 
diff --git a/package/madwifi/patches/324-alignment.patch b/package/madwifi/patches/324-alignment.patch
deleted file mode 100644
index c01135f3e4..0000000000
--- a/package/madwifi/patches/324-alignment.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -1275,14 +1275,8 @@ ieee80211_decap(struct ieee80211vap *vap
- 		eh->ether_type = ether_type;
- 
- 	if (!ALIGNED_POINTER(skb->data + sizeof(*eh), u_int32_t)) {
--		struct sk_buff *tskb;
--
--		/* XXX: does this always work? */
--		tskb = skb_copy(skb, GFP_ATOMIC);
--		if (tskb)
--			ieee80211_skb_copy_noderef(skb, tskb);
--		ieee80211_dev_kfree_skb(&skb);
--		skb = tskb;
-+		memmove(skb->data - 2, skb->data, skb->len);
-+		skb->data -= 2;
- 	}
- 	return skb;
- }
diff --git a/package/madwifi/patches/325-channel_spam.patch b/package/madwifi/patches/325-channel_spam.patch
deleted file mode 100644
index e34b7a4092..0000000000
--- a/package/madwifi/patches/325-channel_spam.patch
+++ /dev/null
@@ -1,28 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -9792,7 +9792,9 @@ ath_getchannels(struct net_device *dev,
- 	/*
- 	 * Convert HAL channels to ieee80211 ones.
- 	 */
-+#ifdef AR_DEBUG
- 	IPRINTF(sc, "HAL returned %d channels.\n", nchan);
-+#endif
- 	for (i = 0; i < nchan; i++) {
- 		HAL_CHANNEL *c = &chans[i];
- 		struct ieee80211_channel *ichan = &ic->ic_channels[i];
-@@ -9819,6 +9821,7 @@ ath_getchannels(struct net_device *dev,
- 		ic->ic_chan_non_occupy[i].tv_sec  = 0;
- 		ic->ic_chan_non_occupy[i].tv_usec = 0;
- 
-+#ifdef AR_DEBUG
- 		IPRINTF(sc, "Channel %3d (%4d MHz) Max Tx Power %d dBm%s "
- 				"[%d hw %d reg] Flags%s%s%s%s%s%s%s%s%s%s%s%s%"
- 				"s%s%s%s%s%s%s%s%s%s%s%s\n",
-@@ -9907,6 +9910,7 @@ ath_getchannels(struct net_device *dev,
- 				(c->privFlags & 0x0080 ? 
- 				 " PF & (1 << 7)" : "")
- 				);
-+#endif
- 	}
- 	ic->ic_nchans = nchan;
- 	kfree(chans);
diff --git a/package/madwifi/patches/327-queue.patch b/package/madwifi/patches/327-queue.patch
deleted file mode 100644
index 228aae3496..0000000000
--- a/package/madwifi/patches/327-queue.patch
+++ /dev/null
@@ -1,40 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -8438,8 +8438,6 @@ process_tx_again:
- 	ath_hal_intrset(sc->sc_ah, sc->sc_imask);
- 	local_irq_restore(flags);
- 
--	netif_wake_queue(dev);
--
- 	if (sc->sc_softled)
- 		ath_led_event(sc, ATH_LED_TX);
- }
-@@ -8486,8 +8484,6 @@ process_tx_again:
- 	ath_hal_intrset(sc->sc_ah, sc->sc_imask);
- 	local_irq_restore(flags);
- 
--	netif_wake_queue(dev);
--
- 	if (sc->sc_softled)
- 		ath_led_event(sc, ATH_LED_TX);
- }
-@@ -8520,8 +8516,6 @@ process_tx_again:
- 	ath_hal_intrset(sc->sc_ah, sc->sc_imask);
- 	local_irq_restore(flags);
- 
--	netif_wake_queue(dev);
--
- 	if (sc->sc_softled)
- 		ath_led_event(sc, ATH_LED_TX);
- }
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -1132,7 +1132,7 @@ ieee80211_deliver_data(struct ieee80211_
- 	    (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0) {
- 		struct sk_buff *skb1 = NULL;
- 
--		if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
-+		if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) {
- 			/* Create a SKB for the BSS to send out. */
- 			skb1 = skb_copy(skb, GFP_ATOMIC);
- 			if (skb1)
diff --git a/package/madwifi/patches/330-beaconcal.patch b/package/madwifi/patches/330-beaconcal.patch
deleted file mode 100644
index a338dc743a..0000000000
--- a/package/madwifi/patches/330-beaconcal.patch
+++ /dev/null
@@ -1,166 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -397,6 +397,7 @@ static int countrycode = -1;
- static int maxvaps = -1;
- static int outdoor = -1;
- static int xchanmode = -1;
-+static int beacon_cal = 1;
- 
- static const char *hal_status_desc[] = {
- 	"No error",
-@@ -422,6 +423,7 @@ static struct notifier_block ath_event_b
- };
- 
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
-+MODULE_PARM(beacon_cal, "i");
- MODULE_PARM(countrycode, "i");
- MODULE_PARM(maxvaps, "i");
- MODULE_PARM(outdoor, "i");
-@@ -434,6 +436,7 @@ MODULE_PARM(autocreate, "s");
- MODULE_PARM(ratectl, "s");
- #else
- #include <linux/moduleparam.h>
-+module_param(beacon_cal, int, 0600);
- module_param(countrycode, int, 0600);
- module_param(maxvaps, int, 0600);
- module_param(outdoor, int, 0600);
-@@ -2600,7 +2603,8 @@ ath_stop_locked(struct net_device *dev)
- 		}
- 		if (!sc->sc_invalid) {
- 			del_timer_sync(&sc->sc_dfs_cac_timer);
--			del_timer_sync(&sc->sc_cal_ch);
-+			if (!sc->sc_beacon_cal)
-+				del_timer_sync(&sc->sc_cal_ch);
- 		}
- 		ath_draintxq(sc);
- 		if (!sc->sc_invalid) {
-@@ -2617,6 +2621,20 @@ ath_stop_locked(struct net_device *dev)
- 	return 0;
- }
- 
-+static void ath_set_beacon_cal(struct ath_softc *sc, int val)
-+{
-+	if (sc->sc_beacon_cal == !!val)
-+		return;
-+
-+	if (val) {
-+		del_timer_sync(&sc->sc_cal_ch);
-+	} else {
-+		sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
-+		add_timer(&sc->sc_cal_ch);
-+	}
-+	sc->sc_beacon_cal = !!val && beacon_cal;
-+}
-+
- /*
-  * Stop the device, grabbing the top-level lock to protect
-  * against concurrent entry through ath_init (which can happen
-@@ -2742,6 +2760,12 @@ ath_reset(struct net_device *dev)
- 	HAL_STATUS status;
- 
- 	/*
-+	 * XXX: starting the calibration too early seems to lead to
-+	 * problems with the beacons.
-+	 */
-+	sc->sc_lastcal = jiffies;
-+
-+	/*
- 	 * Convert to a HAL channel description with the flags
- 	 * constrained to reflect the current operating mode.
- 	 */
-@@ -5154,6 +5178,10 @@ ath_beacon_send(struct ath_softc *sc, in
- 			"Invoking ath_hal_txstart with sc_bhalq: %d\n",
- 			sc->sc_bhalq);
- 		ath_hal_txstart(ah, sc->sc_bhalq);
-+		if (sc->sc_beacon_cal && (jiffies > sc->sc_lastcal + (ath_calinterval * HZ))) {
-+			sc->sc_cal_ch.expires = jiffies + msecs_to_jiffies(10);
-+			add_timer(&sc->sc_cal_ch);
-+		}
- 
- 		sc->sc_stats.ast_be_xmit++;		/* XXX per-VAP? */
- 	}
-@@ -5403,6 +5431,7 @@ ath_beacon_config(struct ath_softc *sc,
- 		ath_hal_beacontimers(ah, &bs);
- 		sc->sc_imask |= HAL_INT_BMISS;
- 		ath_hal_intrset(ah, sc->sc_imask);
-+		ath_set_beacon_cal(sc, 0);
- 	} else {
- 		ath_hal_intrset(ah, 0);
- 		if (reset_tsf)
-@@ -5414,8 +5443,11 @@ ath_beacon_config(struct ath_softc *sc,
- 			 */
- 			intval |= HAL_BEACON_ENA;
- 			sc->sc_imask |= HAL_INT_SWBA;
-+			ath_set_beacon_cal(sc, 1);
- 			ath_beaconq_config(sc);
--		}
-+		} else
-+			ath_set_beacon_cal(sc, 0);
-+
- #ifdef ATH_SUPERG_DYNTURBO
- 		ath_beacon_dturbo_config(vap, intval &
- 				~(HAL_BEACON_RESET_TSF | HAL_BEACON_ENA));
-@@ -8879,6 +8911,9 @@ ath_chan_set(struct ath_softc *sc, struc
- 			/* Enter DFS wait period */
- 			mod_timer(&sc->sc_dfs_cac_timer,
- 				jiffies + (sc->sc_dfs_cac_period * HZ));
-+
-+			/* This is a good time to start a calibration */
-+			ath_set_beacon_cal(sc, 1);
- 		}
- 		/*
- 		 * re configure beacons when it is a turbo mode switch.
-@@ -8988,8 +9023,11 @@ ath_calibrate(unsigned long arg)
- 		sc->sc_curchan.channel, sc->sc_curchan.channelFlags,
- 		isIQdone ? "done" : "not done");
- 
--	sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
--	add_timer(&sc->sc_cal_ch);
-+	sc->sc_lastcal = jiffies;
-+	if (!sc->sc_beacon_cal) {
-+		sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
-+		add_timer(&sc->sc_cal_ch);
-+	}
- }
- 
- static void
-@@ -9096,7 +9134,8 @@ ath_newstate(struct ieee80211vap *vap, e
- 		ieee80211_state_name[vap->iv_state],
- 		ieee80211_state_name[nstate]);
- 
--	del_timer(&sc->sc_cal_ch);		/* periodic calibration timer */
-+	if (!sc->sc_beacon_cal)
-+		del_timer(&sc->sc_cal_ch);		/* periodic calibration timer */
- 
- 	ath_hal_setledstate(ah, leds[nstate]);	/* set LED */
- 	netif_stop_queue(dev);			/* before we do anything else */
-@@ -9321,7 +9360,8 @@ ath_newstate(struct ieee80211vap *vap, e
- 				"VAP -> DFSWAIT_PENDING \n");
- 			/* start calibration timer with a really small value 
- 			 * 1/10 sec */
--			mod_timer(&sc->sc_cal_ch, jiffies + (HZ/10));
-+			if (!sc->sc_beacon_cal)
-+				mod_timer(&sc->sc_cal_ch, jiffies + (HZ/10));
- 			/* wake the receiver */
- 			netif_wake_queue(dev);
- 			/* don't do the other usual stuff... */
-@@ -9364,7 +9404,7 @@ done:
- 	error = avp->av_newstate(vap, nstate, arg);
- 
- 	/* Finally, start any timers. */
--	if (nstate == IEEE80211_S_RUN) {
-+	if (nstate == IEEE80211_S_RUN && !sc->sc_beacon_cal) {
- 		/* start periodic recalibration timer */
- 		mod_timer(&sc->sc_cal_ch, jiffies + (ath_calinterval * HZ));
- 	}
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -778,6 +778,8 @@ struct ath_softc {
- 	struct ieee80211vap **sc_bslot;		/* beacon xmit slots */
- 	int sc_bnext;				/* next slot for beacon xmit */
- 
-+	int sc_beacon_cal;			/* use beacon timer for calibration */
-+	u_int64_t sc_lastcal;			/* last time the calibration was performed */
- 	struct timer_list sc_cal_ch;		/* calibration timer */
- 	HAL_NODE_STATS sc_halstats;		/* station-mode rssi stats */
- 
diff --git a/package/madwifi/patches/331-memory_alloc.patch b/package/madwifi/patches/331-memory_alloc.patch
deleted file mode 100644
index 6b01d79c0d..0000000000
--- a/package/madwifi/patches/331-memory_alloc.patch
+++ /dev/null
@@ -1,36 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -3320,17 +3320,18 @@ ath_hardstart(struct sk_buff *skb, struc
- 	 * without affecting any other bridge ports. */
- 	if (skb_cloned(skb)) {
- 		/* Remember the original SKB so we can free up our references */
--		struct sk_buff *skb_orig = skb;
--		skb = skb_copy(skb, GFP_ATOMIC);
--		if (skb == NULL) {
-+		struct sk_buff *skb_new;
-+		skb_new = skb_copy(skb, GFP_ATOMIC);
-+		if (skb_new == NULL) {
- 			DPRINTF(sc, ATH_DEBUG_XMIT,
- 				"Dropping; skb_copy failure.\n");
- 			/* No free RAM, do not requeue! */
- 			goto hardstart_fail;
- 		}
--		ieee80211_skb_copy_noderef(skb_orig, skb);
--		ieee80211_dev_kfree_skb(&skb_orig);
--	} 
-+		ieee80211_skb_copy_noderef(skb, skb_new);
-+		ieee80211_dev_kfree_skb(&skb);
-+		skb = skb_new;
-+	}
- 	eh = (struct ether_header *)skb->data;
- 
- #ifdef ATH_SUPERG_FF
-@@ -3601,6 +3602,8 @@ ath_mgtstart(struct ieee80211com *ic, st
- 	sc->sc_stats.ast_tx_mgmt++;
- 	return 0;
- bad:
-+	if (skb)
-+		ieee80211_dev_kfree_skb(&skb);
- 	ath_return_txbuf(sc, &bf);
- 	return error;
- }
diff --git a/package/madwifi/patches/332-reset_beacons.patch b/package/madwifi/patches/332-reset_beacons.patch
deleted file mode 100644
index b776426f20..0000000000
--- a/package/madwifi/patches/332-reset_beacons.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -8922,7 +8922,7 @@ ath_chan_set(struct ath_softc *sc, struc
- 		 * re configure beacons when it is a turbo mode switch.
- 		 * HW seems to turn off beacons during turbo mode switch.
- 		 */
--		if (sc->sc_beacons && tswitch && !sc->sc_dfs_cac)
-+		if (sc->sc_beacons && !sc->sc_dfs_cac)
- 			ath_beacon_config(sc, NULL);
- 		/*
- 		 * Re-enable interrupts.
diff --git a/package/madwifi/patches/333-apscan_mode.patch b/package/madwifi/patches/333-apscan_mode.patch
deleted file mode 100644
index 877eea6cef..0000000000
--- a/package/madwifi/patches/333-apscan_mode.patch
+++ /dev/null
@@ -1,15 +0,0 @@
---- a/net80211/ieee80211_scan_ap.c
-+++ b/net80211/ieee80211_scan_ap.c
-@@ -783,12 +783,6 @@ pick_channel(struct ieee80211_scan_state
- 				/* break the loop as the subsequent chans won't be 
- 				 * better */
- 				break;
--
--			if (!IEEE80211_ARE_CHANS_SAME_MODE(c->chan,
--				ic->ic_bsschan))
--				/* break the loop as the subsequent chans won't be 
--				 * better */
--				break;
- 		}
- 
- 		if (sta_assoc != 0) {
diff --git a/package/madwifi/patches/334-input.patch b/package/madwifi/patches/334-input.patch
deleted file mode 100644
index 7c13367014..0000000000
--- a/package/madwifi/patches/334-input.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -950,6 +950,9 @@ ieee80211_input_all(struct ieee80211com
- 	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- 		struct sk_buff *skb1;
- 
-+		if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
-+			continue;
-+
- 		if (TAILQ_NEXT(vap, iv_next) != NULL) {
- 			skb1 = skb_copy(skb, GFP_ATOMIC);
- 			if (skb1 == NULL) {
diff --git a/package/madwifi/patches/340-maxrate.patch b/package/madwifi/patches/340-maxrate.patch
deleted file mode 100644
index ae93f02d26..0000000000
--- a/package/madwifi/patches/340-maxrate.patch
+++ /dev/null
@@ -1,98 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -1307,6 +1307,7 @@ ath_vap_create(struct ieee80211com *ic,
- 	vap->iv_key_set = ath_key_set;
- 	vap->iv_key_update_begin = ath_key_update_begin;
- 	vap->iv_key_update_end = ath_key_update_end;
-+	vap->iv_maxrateindex = 0;
- 	if (sc->sc_default_ieee80211_debug) {
- 		/* User specified defaults for new VAPs were provided, so
- 		 * use those (only). */
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -622,8 +622,12 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 			return;
- 		}
- 		sn->static_rate_ndx = -1;
-+		if (vap->iv_maxrateindex == 0 || ni->ni_rates.rs_nrates <= 0
-+		    || vap->iv_maxrateindex > ni->ni_rates.rs_nrates)
-+			sn->num_rates = ni->ni_rates.rs_nrates;
-+		else
-+			sn->num_rates = vap->iv_maxrateindex;
- 
--		sn->num_rates = ni->ni_rates.rs_nrates;
- 		for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
- 			sn->rs_rateattempts 	[x] = 0;
- 			sn->rs_thisprob 	[x] = 0;
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -835,7 +835,12 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 	}
- 	sn->static_rate_ndx = -1;
- 
--	sn->num_rates = ni->ni_rates.rs_nrates;
-+	if (vap->iv_maxrateindex == 0 || ni->ni_rates.rs_nrates <= 0
-+	    || vap->iv_maxrateindex > ni->ni_rates.rs_nrates)
-+		sn->num_rates = ni->ni_rates.rs_nrates;
-+	else
-+		sn->num_rates = vap->iv_maxrateindex;
-+
- 	for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
- 		sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
- 		sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -641,6 +641,7 @@ enum {
- 							   FCC requires 30m, so that is the default. */
- 	IEEE80211_PARAM_BEACON_MISS_THRESH	= 73,	/* Beacon miss threshold (in beacons) */
- 	IEEE80211_PARAM_BEACON_MISS_THRESH_MS	= 74,	/* Beacon miss threshold (in ms) */
-+	IEEE80211_PARAM_MAXRATE			= 75,	/* Maximum rate (by table index) */
- };
- 
- #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -281,6 +281,7 @@ struct ieee80211vap {
- 	struct ieee80211_spy iv_spy;         		/* IWSPY support */
- 	struct ieee80211_app_ie app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */
- 	u_int32_t app_filter;				/* filters which management frames are forwarded to app */
-+	u_int iv_maxrateindex;
- };
- 
- /* Debug functions need the defintion of struct ieee80211vap because iv_debug 
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2839,6 +2839,12 @@ ieee80211_ioctl_setparam(struct net_devi
- 		else
- 			ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS;
- 		break;
-+	case IEEE80211_PARAM_MAXRATE:
-+		if (value > 0)
-+			vap->iv_maxrateindex = value;
-+		else
-+			vap->iv_maxrateindex = 0;
-+		break;
- #ifdef ATH_REVERSE_ENGINEERING
- 	case IEEE80211_PARAM_DUMPREGS:
- 		ieee80211_dump_registers(dev, info, w, extra);
-@@ -3174,6 +3180,9 @@ ieee80211_ioctl_getparam(struct net_devi
- 		else
- 			param[0] = 0;
- 		break;
-+	case IEEE80211_PARAM_MAXRATE:
-+		param[0] = vap->iv_maxrateindex;
-+		break;
- 	default:
- 		return -EOPNOTSUPP;
- 	}
-@@ -5610,6 +5619,10 @@ static const struct iw_priv_args ieee802
- 	  0, IW_PRIV_TYPE_APPIEBUF, "getiebuf" },
- 	{ IEEE80211_IOCTL_FILTERFRAME,
- 	  IW_PRIV_TYPE_FILTER , 0, "setfilter" },
-+	{IEEE80211_PARAM_MAXRATE,
-+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxrate"},
-+	{IEEE80211_PARAM_MAXRATE,
-+	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxrate"},
- 
- #ifdef ATH_REVERSE_ENGINEERING
- 	/*
diff --git a/package/madwifi/patches/341-minrate.patch b/package/madwifi/patches/341-minrate.patch
deleted file mode 100644
index cc04ae074c..0000000000
--- a/package/madwifi/patches/341-minrate.patch
+++ /dev/null
@@ -1,114 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -1308,6 +1308,7 @@ ath_vap_create(struct ieee80211com *ic,
- 	vap->iv_key_update_begin = ath_key_update_begin;
- 	vap->iv_key_update_end = ath_key_update_end;
- 	vap->iv_maxrateindex = 0;
-+	vap->iv_minrateindex = 0;
- 	if (sc->sc_default_ieee80211_debug) {
- 		/* User specified defaults for new VAPs were provided, so
- 		 * use those (only). */
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -638,9 +638,15 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 			sn->rs_succ_hist	[x] = 0;
- 			sn->rs_att_hist 	[x] = 0;
- 			sn->rs_this_tp 		[x] = 0;
--
-+			if (vap->iv_minrateindex && vap->iv_minrateindex<ni->ni_rates.rs_nrates)
-+			{
-+			int idx = vap->iv_minrateindex; 
-+			sn->rates[x].rate = ni->ni_rates.rs_rates[idx] & IEEE80211_RATE_VAL;
-+			sn->rates[x].rix = sc->sc_rixmap[sn->rates[idx].rate];
-+			}else{
- 			sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
- 			sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
-+			}
- 			if (sn->rates[x].rix == 0xff) {
- 				DPRINTF(sc, "%s: %s ignore bogus rix at %d\n",
- 					dev_info, __func__, x);
-@@ -649,7 +655,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 			sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode;
- 			sn->rates[x].shortPreambleRateCode =
- 				rt->info[sn->rates[x].rix].rateCode |
--				rt->info[sn->rates[x].rix].shortPreamble;
-+				rt->info[sn->rates[x].rix].shortPreamble;			
- 		}
- 
- 		ath_fill_sample_table(sn);
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -842,8 +842,15 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 		sn->num_rates = vap->iv_maxrateindex;
- 
- 	for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
--		sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
--		sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
-+		if (vap->iv_minrateindex && vap->iv_minrateindex<ni->ni_rates.rs_nrates)
-+			{
-+			int idx = vap->iv_minrateindex; 
-+			sn->rates[x].rate = ni->ni_rates.rs_rates[idx] & IEEE80211_RATE_VAL;
-+			sn->rates[x].rix = sc->sc_rixmap[sn->rates[idx].rate];
-+			}else{
-+			sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
-+			sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
-+			}
- 		if (sn->rates[x].rix == 0xff) {
- 			DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s ignore bogus rix at %u\n",
- 				dev_info, __func__, x);
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -642,6 +642,7 @@ enum {
- 	IEEE80211_PARAM_BEACON_MISS_THRESH	= 73,	/* Beacon miss threshold (in beacons) */
- 	IEEE80211_PARAM_BEACON_MISS_THRESH_MS	= 74,	/* Beacon miss threshold (in ms) */
- 	IEEE80211_PARAM_MAXRATE			= 75,	/* Maximum rate (by table index) */
-+	IEEE80211_PARAM_MINRATE			= 76,	/* Minimum rate (by table index) */
- };
- 
- #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -282,6 +282,7 @@ struct ieee80211vap {
- 	struct ieee80211_app_ie app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */
- 	u_int32_t app_filter;				/* filters which management frames are forwarded to app */
- 	u_int iv_maxrateindex;
-+	u_int iv_minrateindex;
- };
- 
- /* Debug functions need the defintion of struct ieee80211vap because iv_debug 
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2845,6 +2845,12 @@ ieee80211_ioctl_setparam(struct net_devi
- 		else
- 			vap->iv_maxrateindex = 0;
- 		break;
-+	case IEEE80211_PARAM_MINRATE:
-+		if (value > 0)
-+			vap->iv_minrateindex = value;
-+		else
-+			vap->iv_minrateindex = 0;
-+		break;
- #ifdef ATH_REVERSE_ENGINEERING
- 	case IEEE80211_PARAM_DUMPREGS:
- 		ieee80211_dump_registers(dev, info, w, extra);
-@@ -3183,6 +3189,9 @@ ieee80211_ioctl_getparam(struct net_devi
- 	case IEEE80211_PARAM_MAXRATE:
- 		param[0] = vap->iv_maxrateindex;
- 		break;
-+	case IEEE80211_PARAM_MINRATE:
-+		param[0] = vap->iv_minrateindex;
-+		break;
- 	default:
- 		return -EOPNOTSUPP;
- 	}
-@@ -5623,6 +5632,10 @@ static const struct iw_priv_args ieee802
- 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxrate"},
- 	{IEEE80211_PARAM_MAXRATE,
- 	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxrate"},
-+	{IEEE80211_PARAM_MINRATE,
-+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"},
-+	{IEEE80211_PARAM_MINRATE,
-+	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"},
- 
- #ifdef ATH_REVERSE_ENGINEERING
- 	/*
diff --git a/package/madwifi/patches/342-performance.patch b/package/madwifi/patches/342-performance.patch
deleted file mode 100644
index 88cec182dd..0000000000
--- a/package/madwifi/patches/342-performance.patch
+++ /dev/null
@@ -1,263 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -3239,7 +3239,6 @@ ath_hardstart(struct sk_buff *skb, struc
- 	struct ath_softc *sc = dev->priv;
- 	struct ieee80211_node *ni = NULL;
- 	struct ath_buf *bf = NULL;
--	struct ether_header *eh;
- 	ath_bufhead bf_head;
- 	struct ath_buf *tbf, *tempbf;
- 	struct sk_buff *tskb;
-@@ -3251,6 +3250,7 @@ ath_hardstart(struct sk_buff *skb, struc
- 	*/
- 	int requeue = 0;
- #ifdef ATH_SUPERG_FF
-+	struct ether_header *eh;
- 	unsigned int pktlen;
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_node *an;
-@@ -3316,27 +3316,9 @@ ath_hardstart(struct sk_buff *skb, struc
- 		requeue = 1;
- 		goto hardstart_fail;
- 	}
--#endif
- 
--	/* If the skb data is shared, we will copy it so we can strip padding
--	 * without affecting any other bridge ports. */
--	if (skb_cloned(skb)) {
--		/* Remember the original SKB so we can free up our references */
--		struct sk_buff *skb_new;
--		skb_new = skb_copy(skb, GFP_ATOMIC);
--		if (skb_new == NULL) {
--			DPRINTF(sc, ATH_DEBUG_XMIT,
--				"Dropping; skb_copy failure.\n");
--			/* No free RAM, do not requeue! */
--			goto hardstart_fail;
--		}
--		ieee80211_skb_copy_noderef(skb, skb_new);
--		ieee80211_dev_kfree_skb(&skb);
--		skb = skb_new;
--	}
- 	eh = (struct ether_header *)skb->data;
- 
--#ifdef ATH_SUPERG_FF
- 	/* NB: use this lock to protect an->an_tx_ffbuf (and txq->axq_stageq)
- 	 *     in athff_can_aggregate() call too. */
- 	ATH_TXQ_LOCK_IRQ(txq);
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -283,7 +283,7 @@ ieee80211_hardstart(struct sk_buff *skb,
- 	 * normal vap. */
- 	if (vap->iv_xrvap && (ni == vap->iv_bss) &&
- 	    vap->iv_xrvap->iv_sta_assoc) {
--		struct sk_buff *skb1 = skb_copy(skb, GFP_ATOMIC);
-+		struct sk_buff *skb1 = skb_clone(skb, GFP_ATOMIC);
- 		if (skb1) {
- 			memset(SKB_CB(skb1), 0, sizeof(struct ieee80211_cb));
- #ifdef IEEE80211_DEBUG_REFCNT
-@@ -566,7 +566,7 @@ ieee80211_skbhdr_adjust(struct ieee80211
- 	struct ieee80211_key *key, struct sk_buff *skb, int ismulticast)
- {
- 	/* XXX pre-calculate per node? */
--	int need_headroom = LLC_SNAPFRAMELEN + hdrsize + IEEE80211_ADDR_LEN;
-+	int need_headroom = LLC_SNAPFRAMELEN + hdrsize;
- 	int need_tailroom = 0;
- #ifdef ATH_SUPERG_FF
- 	int isff = ATH_FF_MAGIC_PRESENT(skb);
-@@ -608,109 +608,56 @@ ieee80211_skbhdr_adjust(struct ieee80211
- 				need_tailroom += cip->ic_miclen;
- 	}
- 
--	if (skb_shared(skb)) {
--		/* Take our own reference to the node in the clone */
--		ieee80211_ref_node(SKB_CB(skb)->ni);
--		/* Unshare the node, decrementing users in the old skb */
--		skb = skb_unshare(skb, GFP_ATOMIC);
--	}
-+	need_headroom -= skb_headroom(skb);
-+	if (isff)
-+		need_tailroom -= skb_tailroom(skb2);
-+	else
-+		need_tailroom -= skb_tailroom(skb);
-+
-+	if (need_headroom < 0)
-+		need_headroom = 0;
-+	if (need_tailroom < 0)
-+		need_tailroom = 0;
- 
--#ifdef ATH_SUPERG_FF
--	if (isff) {
--		if (skb == NULL) {
--			IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
--				"%s: cannot unshare for encapsulation\n",
--				__func__);
--			vap->iv_stats.is_tx_nobuf++;
--			ieee80211_dev_kfree_skb(&skb2);
-+	if (skb_cloned(skb) || (need_headroom > 0) ||
-+		(!isff && (need_tailroom > 0))) {
- 
--			return NULL;
-+		if (pskb_expand_head(skb, need_headroom, need_tailroom, GFP_ATOMIC)) {
-+			IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
-+				"%s: cannot expand storage (tail)\n", __func__);
-+			goto error;
- 		}
-+	}
- 
--		/* first skb header */
--		if (skb_headroom(skb) < need_headroom) {
--			struct sk_buff *tmp = skb;
--			skb = skb_realloc_headroom(skb, need_headroom);
--			if (skb == NULL) {
--				IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
--					"%s: cannot expand storage (head1)\n",
--					__func__);
--				vap->iv_stats.is_tx_nobuf++;
--				ieee80211_dev_kfree_skb(&skb2);
--				return NULL;
--			} else
--				ieee80211_skb_copy_noderef(tmp, skb);
--			ieee80211_dev_kfree_skb(&tmp);
--			/* NB: cb[] area was copied, but not next ptr. must do that
--			 *     prior to return on success. */
--		}
-+#ifdef ATH_SUPERG_FF
-+	if (isff) {
-+		inter_headroom -= skb_headroom(skb2);
-+		if (inter_headroom < 0)
-+			inter_headroom = 0;
-+		if ((skb_cloned(skb2) ||
-+			(inter_headroom > 0) || (need_tailroom > 0))) {
- 
--		/* second skb with header and tail adjustments possible */
--		if (skb_tailroom(skb2) < need_tailroom) {
--			int n = 0;
--			if (inter_headroom > skb_headroom(skb2))
--				n = inter_headroom - skb_headroom(skb2);
--			if (pskb_expand_head(skb2, n,
--			    need_tailroom - skb_tailroom(skb2), GFP_ATOMIC)) {
--				ieee80211_dev_kfree_skb(&skb2);
-+			if (pskb_expand_head(skb2, inter_headroom,
-+				need_tailroom, GFP_ATOMIC)) {
- 				IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
--					"%s: cannot expand storage (tail2)\n",
--					__func__);
--				vap->iv_stats.is_tx_nobuf++;
--				/* this shouldn't happen, but don't send first ff either */
--				ieee80211_dev_kfree_skb(&skb);
-+					"%s: cannot expand storage (tail)\n", __func__);
-+				goto error;
- 			}
--		} else if (skb_headroom(skb2) < inter_headroom) {
--			struct sk_buff *tmp = skb2;
--
--			skb2 = skb_realloc_headroom(skb2, inter_headroom);
--			if (skb2 == NULL) {
--				IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
--					"%s: cannot expand storage (head2)\n",
--					__func__);
--				vap->iv_stats.is_tx_nobuf++;
--				/* this shouldn't happen, but don't send first ff either */
--				ieee80211_dev_kfree_skb(&skb);
--				skb = NULL;
--			} else
--				ieee80211_skb_copy_noderef(tmp, skb);
--			ieee80211_dev_kfree_skb(&tmp);
--		}
--		if (skb) {
--			skb->next = skb2;
- 		}
--		return skb;
-+		skb->next = skb2;
- 	}
- #endif /* ATH_SUPERG_FF */
--	if (skb == NULL) {
--		IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
--			"%s: cannot unshare for encapsulation\n", __func__);
--		vap->iv_stats.is_tx_nobuf++;
--	} else if (skb_tailroom(skb) < need_tailroom) {
--		int n = 0;
--		if (need_headroom > skb_headroom(skb))
--			n = need_headroom - skb_headroom(skb);
--		if (pskb_expand_head(skb, n, need_tailroom - 
--					skb_tailroom(skb), GFP_ATOMIC)) {
--			IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
--				"%s: cannot expand storage (tail)\n", __func__);
--			vap->iv_stats.is_tx_nobuf++;
--			ieee80211_dev_kfree_skb(&skb);
--		}
--	} else if (skb_headroom(skb) < need_headroom) {
--		struct sk_buff *tmp = skb;
--		skb = skb_realloc_headroom(skb, need_headroom);
--		/* Increment reference count after copy */
--		if (skb == NULL) {
--			IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
--				"%s: cannot expand storage (head)\n", __func__);
--			vap->iv_stats.is_tx_nobuf++;
--		} else
--			ieee80211_skb_copy_noderef(tmp, skb);
--		ieee80211_dev_kfree_skb(&tmp);
--	}
- 
- 	return skb;
-+
-+error:
-+	vap->iv_stats.is_tx_nobuf++;
-+	ieee80211_dev_kfree_skb(&skb);
-+#ifdef ATH_SUPERG_FF
-+	if (skb2)
-+		ieee80211_dev_kfree_skb(&skb2);
-+#endif
-+	return NULL;
- }
- 
- #define	KEY_UNDEFINED(k)	((k).wk_cipher == &ieee80211_cipher_none)
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -204,7 +204,6 @@ ieee80211_input(struct ieee80211vap * va
- 	struct ieee80211_frame *wh;
- 	struct ieee80211_key *key;
- 	struct ether_header *eh;
--	struct sk_buff *skb2;
- #ifdef ATH_SUPERG_FF
- 	struct llc *llc;
- #endif
-@@ -244,20 +243,6 @@ ieee80211_input(struct ieee80211vap * va
- 		vap->iv_stats.is_rx_tooshort++;
- 		goto out;
- 	}
--	/* Clone the SKB... we assume somewhere in this driver that we 'own'
--	 * the skbuff passed into hard start and we do a lot of messing with it
--	 * but bridges under some cases will not clone for the first pass of skb
--	 * to a bridge port, but will then clone for subsequent ones.  This is 
--	 * odd behavior but it means that if we have trashed the skb we are given
--	 * then other ports get clones of the residual garbage.
--	 */
--	if ((skb2 = skb_copy(skb, GFP_ATOMIC)) == NULL) {
--		vap->iv_devstats.tx_dropped++;
--		goto out;
--	}
--	ieee80211_skb_copy_noderef(skb, skb2);
--	ieee80211_dev_kfree_skb(&skb);
--	skb = skb2;
- 
- 	/*
- 	 * Bit of a cheat here, we use a pointer for a 3-address
-@@ -738,7 +723,7 @@ ieee80211_input(struct ieee80211vap * va
- 			/* ether_type must be length as FF frames are always LLC/SNAP encap'd */ 
- 			frame_len = ntohs(eh_tmp->ether_type); 
- 
--			skb1 = skb_copy(skb, GFP_ATOMIC);
-+			skb1 = skb_clone(skb, GFP_ATOMIC);
- 			if (skb1 == NULL)
- 				goto err;
- 			ieee80211_skb_copy_noderef(skb, skb1);
-@@ -1137,7 +1122,7 @@ ieee80211_deliver_data(struct ieee80211_
- 
- 		if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) {
- 			/* Create a SKB for the BSS to send out. */
--			skb1 = skb_copy(skb, GFP_ATOMIC);
-+			skb1 = skb_clone(skb, GFP_ATOMIC);
- 			if (skb1)
- 				SKB_CB(skb1)->ni = ieee80211_ref_node(vap->iv_bss); 
- 		}
diff --git a/package/madwifi/patches/343-txqueue_races.patch b/package/madwifi/patches/343-txqueue_races.patch
deleted file mode 100644
index a2b14d69a8..0000000000
--- a/package/madwifi/patches/343-txqueue_races.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-Merged from madwifi trunk r3551, r3552
-
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -8253,6 +8253,17 @@ ath_tx_processq(struct ath_softc *sc, st
- 			goto bf_fail;
- 		}
- 
-+		/* We make sure we don't remove the TX descriptor on
-+		 * which the HW is pointing since it contains the
-+		 * ds_link field, except if this is the last TX
-+		 * descriptor in the queue */
-+
-+		if ((txq->axq_depth > 1) &&
-+		    (bf->bf_daddr == ath_hal_gettxbuf(ah, txq->axq_qnum))) {
-+			ATH_TXQ_UNLOCK_IRQ_EARLY(txq);
-+			goto bf_fail;
-+		}
-+
- 		ATH_TXQ_REMOVE_HEAD(txq, bf_list);
- 		ATH_TXQ_UNLOCK_IRQ(txq);
- 
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -586,7 +586,8 @@ struct ath_vap {
- } while (0)
- #define ATH_TXQ_REMOVE_HEAD(_tq, _field) do { \
- 	STAILQ_REMOVE_HEAD(&(_tq)->axq_q, _field); \
--	(_tq)->axq_depth--; \
-+	if (--(_tq)->axq_depth <= 0) \
-+		(_tq)->axq_link = NULL; \
- } while (0)
- /* move buffers from MCASTQ to CABQ */
- #define ATH_TXQ_MOVE_MCASTQ(_tqs,_tqd) do { \
diff --git a/package/madwifi/patches/344-minstrel_failcnt.patch b/package/madwifi/patches/344-minstrel_failcnt.patch
deleted file mode 100644
index ea92dc4d60..0000000000
--- a/package/madwifi/patches/344-minstrel_failcnt.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -475,7 +475,7 @@ ath_rate_tx_complete(struct ath_softc *s
- 		/* 'tries' is the total number of times we have endeavoured to
- 		 * send this packet, and is a sum of the #attempts at each
- 		 * level in the multi-rate retry chain */
--		tries = ts->ts_shortretry + ts->ts_longretry + 1;
-+		tries = ts->ts_longretry + 1;
- 
- 		if (sn->num_rates <= 0) {
- 			DPRINTF(sc, "%s: " MAC_FMT " %s no rates yet\n", dev_info,
diff --git a/package/madwifi/patches/345-minstrel_sampling.patch b/package/madwifi/patches/345-minstrel_sampling.patch
deleted file mode 100644
index 63fcb8a613..0000000000
--- a/package/madwifi/patches/345-minstrel_sampling.patch
+++ /dev/null
@@ -1,80 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -8103,6 +8103,7 @@ ath_tx_start(struct net_device *dev, str
- 		ath_hal_setupxtxdesc(sc->sc_ah, ds, mrr.rate1, mrr.retries1,
- 				     mrr.rate2, mrr.retries2,
- 				     mrr.rate3, mrr.retries3);
-+		bf->rcflags = mrr.privflags;
- 	}
- 
- #ifndef ATH_SUPERG_FF
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -446,6 +446,7 @@ struct ath_buf {
- 	u_int16_t bf_flags;				/* tx descriptor flags */
- 	u_int64_t bf_tsf;
- 	int16_t bf_channoise;
-+	unsigned int rcflags;
- #ifdef ATH_SUPERG_FF
- 	/* XXX: combine this with bf_skbaddr if it ever changes to accommodate
- 	 *      multiple segments.
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -333,15 +333,19 @@ ath_rate_findrate(struct ath_softc *sc,
- 		if (sn->static_rate_ndx >= 0) {
- 			    ndx = sn->static_rate_ndx;
- 		} else {
-+			int delta;
- 			sn->packet_count++;
- 			sn->random_n = (sn->a * sn->random_n) + sn->b;
- 			offset = sn->random_n & 0xf;
--			if ((((100 * sn->sample_count) / (sn->sample_count + sn->packet_count)) < ath_lookaround_rate) && (offset < 2)) {
-+			delta = (sn->packet_count * ath_lookaround_rate / 100) - sn->sample_count;
-+			if ((delta > 0) && (offset < 2)) {
- 				sn->sample_count++;
- 				sn->is_sampling = 1;
- 				if (sn->packet_count >= 10000) {
- 					sn->sample_count = 0;
- 					sn->packet_count = 0;
-+				} else if (delta > sn->num_rates * 2) {
-+					sn->sample_count += ((delta - sn->num_rates * 2) * ath_lookaround_rate) / 100;
- 				}
- 
- 				/* Don't look for slowest rate (i.e. slowest
-@@ -398,11 +402,14 @@ ath_rate_get_mrr(struct ath_softc *sc, s
- 		if (sn->num_rates <= 0)
- 			return;
- 
-+		mrr->privflags = sn->is_sampling;
- 		if (sn->is_sampling) {
- 			sn->is_sampling = 0;
--			if (sn->rs_sample_rate_slower)
-+			if (sn->rs_sample_rate_slower) {
- 				rc1 = sn->rs_sample_rate;
--			else
-+				if (sn->sample_count > 0)
-+					sn->sample_count--;
-+			} else
- 				rc1 = sn->max_tp_rate;
- 		} else {
- 			rc1 = sn->max_tp_rate2;
-@@ -525,6 +532,9 @@ ath_rate_tx_complete(struct ath_softc *s
- 		if (tries <= tries1)
- 			return;
- 
-+		if (bf->rcflags)
-+			sn->sample_count++;
-+
- 		if  (tries2 < 0)
- 			return;
- 		tries = tries - tries1;
---- a/net80211/ieee80211_rate.h
-+++ b/net80211/ieee80211_rate.h
-@@ -87,6 +87,7 @@ struct ieee80211_mrr {
- 	int retries2;
- 	int rate3;
- 	int retries3;
-+	int privflags;
- };
- 
- struct ieee80211_rate_ops {
diff --git a/package/madwifi/patches/346-protmode_trig.patch b/package/madwifi/patches/346-protmode_trig.patch
deleted file mode 100644
index 5b5cec6e98..0000000000
--- a/package/madwifi/patches/346-protmode_trig.patch
+++ /dev/null
@@ -1,135 +0,0 @@
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -333,7 +333,9 @@ ieee80211_ifattach(struct ieee80211com *
- 			IEEE80211_MS_TO_TU(IEEE80211_BMISSTHRESH_DEFAULT_MS), 
- 			ic->ic_lintval), ic->ic_lintval);
- 	}
--		
-+	ic->ic_protmode_timeout = IEEE80211_PROTMODE_TIMEOUT;
-+	ic->ic_protmode_rssi = IEEE80211_PROTMODE_RSSITHR;
-+
- 	IEEE80211_LOCK_INIT(ic, "ieee80211com");
- 	IEEE80211_VAPS_LOCK_INIT(ic, "ieee80211com_vaps");
- 	TAILQ_INIT(&ic->ic_vaps);
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -3411,14 +3411,18 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
- 
- 			/* Assume no ERP IE == 11b AP */
--			if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
--				!(ic->ic_flags & IEEE80211_F_USEPROT)) {
-+			if ((!has_erp || (has_erp &&
-+				(scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
-+				(rssi > ic->ic_protmode_rssi)) {
- 				struct ieee80211vap *tmpvap;
- 
--				ic->ic_flags |= IEEE80211_F_USEPROT;
--				TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
--					tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+				if (!(ic->ic_flags & IEEE80211_F_USEPROT)) {
-+					ic->ic_flags |= IEEE80211_F_USEPROT;
-+					TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
-+						tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+					}
- 				}
-+				ic->ic_protmode_lasttrig = jiffies;
- 			}
- 		}
- 
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -643,6 +643,8 @@ enum {
- 	IEEE80211_PARAM_BEACON_MISS_THRESH_MS	= 74,	/* Beacon miss threshold (in ms) */
- 	IEEE80211_PARAM_MAXRATE			= 75,	/* Maximum rate (by table index) */
- 	IEEE80211_PARAM_MINRATE			= 76,	/* Minimum rate (by table index) */
-+	IEEE80211_PARAM_PROTMODE_RSSI		= 77,	/* RSSI Threshold for enabling protection mode */
-+	IEEE80211_PARAM_PROTMODE_TIMEOUT	= 78,	/* Timeout for expiring protection mode */
- };
- 
- #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -128,6 +128,9 @@
- 
- #define	IEEE80211_APPIE_MAX	1024
- 
-+#define IEEE80211_PROTMODE_RSSITHR	15	/* default rssi threshold for protection mode trigger */
-+#define IEEE80211_PROTMODE_TIMEOUT	30	/* timeout for keeping protection mode alive */
-+
- #define IEEE80211_PWRCONSTRAINT_VAL(ic) \
- 	(((ic)->ic_bsschan->ic_maxregpower > (ic)->ic_curchanmaxpwr) ? \
- 	    (ic)->ic_bsschan->ic_maxregpower - (ic)->ic_curchanmaxpwr : 0)
-@@ -324,6 +327,9 @@ struct ieee80211com {
- 	u_int16_t ic_newtxpowlimit; 		/* tx power limit to change to (in 0.5 dBm) */
- 	u_int16_t ic_uapsdmaxtriggers; 		/* max triggers that could arrive */
- 	u_int8_t ic_coverageclass; 		/* coverage class */
-+	u_int8_t ic_protmode_rssi;			/* rssi threshold for protection mode */
-+	u_int64_t ic_protmode_lasttrig;		/* last trigger for protection mode */
-+	u_int16_t ic_protmode_timeout;		/* protection mode timeout */
- 
- 	/* Channel state:
- 	 *
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2312,6 +2312,12 @@ ieee80211_ioctl_setparam(struct net_devi
- 		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
- 			retv = ENETRESET;
- 		break;
-+	case IEEE80211_PARAM_PROTMODE_TIMEOUT:
-+		ic->ic_protmode_timeout = value;
-+		break;
-+	case IEEE80211_PARAM_PROTMODE_RSSI:
-+		ic->ic_protmode_rssi = value;
-+		break;
- 	case IEEE80211_PARAM_MCASTCIPHER:
- 		if ((vap->iv_caps & cipher2cap(value)) == 0 &&
- 		    !ieee80211_crypto_available(vap, value))
-@@ -2955,6 +2961,12 @@ ieee80211_ioctl_getparam(struct net_devi
- 	case IEEE80211_PARAM_PROTMODE:
- 		param[0] = ic->ic_protmode;
- 		break;
-+	case IEEE80211_PARAM_PROTMODE_TIMEOUT:
-+		param[0] = ic->ic_protmode_timeout;
-+		break;
-+	case IEEE80211_PARAM_PROTMODE_RSSI:
-+		param[0] = ic->ic_protmode_rssi;
-+		break;
- 	case IEEE80211_PARAM_MCASTCIPHER:
- 		param[0] = rsn->rsn_mcastcipher;
- 		break;
-@@ -5346,6 +5358,14 @@ static const struct iw_priv_args ieee802
- 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protmode" },
- 	{ IEEE80211_PARAM_PROTMODE,
- 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protmode" },
-+	{ IEEE80211_PARAM_PROTMODE_RSSI,
-+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protrssi" },
-+	{ IEEE80211_PARAM_PROTMODE_RSSI,
-+	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protrssi" },
-+	{ IEEE80211_PARAM_PROTMODE_TIMEOUT,
-+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prottime" },
-+	{ IEEE80211_PARAM_PROTMODE_TIMEOUT,
-+	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_prottime" },
- 	{ IEEE80211_PARAM_MCASTCIPHER,
- 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcastcipher" },
- 	{ IEEE80211_PARAM_MCASTCIPHER,
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -1877,6 +1877,17 @@ ieee80211_node_timeout(unsigned long arg
- 
- 	ieee80211_scan_timeout(ic);
- 	ieee80211_timeout_stations(&ic->ic_sta);
-+	if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
-+		(ic->ic_protmode_lasttrig + ic->ic_protmode_timeout * HZ <
-+			jiffies)) {
-+		struct ieee80211vap *tmpvap;
-+
-+		/* expire protection mode */
-+		ic->ic_flags &= ~IEEE80211_F_USEPROT;
-+		TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
-+			tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
-+		}
-+	}
- 
- 	ic->ic_inact.expires = jiffies + IEEE80211_INACT_WAIT * HZ;
- 	add_timer(&ic->ic_inact);
diff --git a/package/madwifi/patches/347-tuning.patch b/package/madwifi/patches/347-tuning.patch
deleted file mode 100644
index 1a73c42747..0000000000
--- a/package/madwifi/patches/347-tuning.patch
+++ /dev/null
@@ -1,99 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -10276,11 +10276,11 @@ ath_setcurmode(struct ath_softc *sc, enu
- 	sc->sc_currates = rt;
- 	sc->sc_curmode = mode;
- 	/*
--	 * All protection frames are transmitted at 2Mb/s for
--	 * 11g, otherwise at 1Mb/s.
-+	 * All protection frames are transmitted at 11Mb/s for
-+	 * 11g, otherwise at 2Mb/s.
- 	 * XXX select protection rate index from rate table.
- 	 */
--	sc->sc_protrix = (mode == IEEE80211_MODE_11G ? 1 : 0);
-+	sc->sc_protrix = (mode == IEEE80211_MODE_11G ? 3 : 1);
- 	/* rate index used to send mgt frames */
- 	sc->sc_minrateix = 0;
- }
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -272,6 +272,10 @@ static inline struct net_device *_alloc_
- #define AES_ICV_FIELD_SIZE      8       /* AES ICV field size */
- #define EXT_IV_FIELD_SIZE       4       /* ext IV field size */
- 
-+/* This is what the HAL uses by default for 11a+g */
-+#define ATH_DEFAULT_CWMIN	15
-+#define ATH_DEFAULT_CWMAX	1023
-+
- /* XR specific macros */
- 
- #define XR_DEFAULT_GRPPOLL_RATE_STR 	"0.25 1 1 3 3 6 6 20"
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -197,7 +197,7 @@ calc_usecs_unicast_packet(struct ath_sof
- 		unsigned int x = 0, tt = 0;
- 		unsigned int cix = rt->info[rix].controlRate;
- 		int rts = 0, cts = 0;
--		int cw = WIFI_CW_MIN;
-+		int cw = ATH_DEFAULT_CWMIN;
- 
- 		KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
- 
-@@ -281,7 +281,7 @@ calc_usecs_unicast_packet(struct ath_sof
- 		tt += (long_retries + 1) * ath_hal_computetxtime(sc->sc_ah, rt, length,
- 							rix, AH_TRUE);
- 		for (x = 0; x <= short_retries + long_retries; x++) {
--			cw = MIN(WIFI_CW_MAX, (cw + 1) * 2);
-+			cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2);
- 			tt += (t_slot * cw / 2);
- 		}
- 		return tt;
---- a/ath_rate/minstrel/minstrel.h
-+++ b/ath_rate/minstrel/minstrel.h
-@@ -180,14 +180,6 @@ struct minstrel_node {
- #define MAX(a,b)        ((a) > (b) ? (a) : (b))
- #endif
- 
--#if 0
--#define WIFI_CW_MIN 31
--#define WIFI_CW_MAX 1023
--#else
--#define WIFI_CW_MIN 3
--#define WIFI_CW_MAX 10
--#endif
--
- /*
-  * Definitions for pulling the rate and trie counts from
-  * a 5212 h/w descriptor. These Don't belong here; the
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -170,7 +170,7 @@ calc_usecs_unicast_packet(struct ath_sof
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	unsigned int tt = 0;
- 	unsigned int x;
--	unsigned int cw = WIFI_CW_MIN;
-+	unsigned int cw = ATH_DEFAULT_CWMIN;
- 	unsigned int cix = rt->info[rix].controlRate;
- 	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
- 
-@@ -254,7 +254,7 @@ calc_usecs_unicast_packet(struct ath_sof
- 	tt += (long_retries+1)*ath_hal_computetxtime(sc->sc_ah, rt, length,
- 						rix, AH_TRUE);
- 	for (x = 0; x <= short_retries + long_retries; x++) {
--		cw = MIN(WIFI_CW_MAX, (cw + 1) * 2);
-+		cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2);
- 		tt += (t_slot * cw / 2);
- 	}
- 	return tt;
---- a/ath_rate/sample/sample.h
-+++ b/ath_rate/sample/sample.h
-@@ -106,9 +106,6 @@ struct sample_node {
- #define MAX(a,b)        ((a) > (b) ? (a) : (b))
- #endif
- 
--#define WIFI_CW_MIN 31
--#define WIFI_CW_MAX 1023
--
- /*
-  * Definitions for pulling the rate and trie counts from
-  * a 5212 h/w descriptor. These Don't belong here; the
diff --git a/package/madwifi/patches/348-ackcts.patch b/package/madwifi/patches/348-ackcts.patch
deleted file mode 100644
index 42b6fe2613..0000000000
--- a/package/madwifi/patches/348-ackcts.patch
+++ /dev/null
@@ -1,38 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -2723,6 +2723,9 @@ ar_device(int devid)
- static int
- ath_set_ack_bitrate(struct ath_softc *sc, int high)
- {
-+	if (!sc->sc_ackrate_override)
-+		return 0;
-+
- 	if (ar_device(sc->devid) == 5212 || ar_device(sc->devid) == 5213) {
- 		/* set ack to be sent at low bit-rate */
- 		/* registers taken from the OpenBSD 5212 HAL */
-@@ -10791,8 +10794,13 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 				break;
- #endif
- 			case ATH_ACKRATE:
--				sc->sc_ackrate = val;
--				ath_set_ack_bitrate(sc, sc->sc_ackrate);
-+				if (val == -1)
-+					sc->sc_ackrate_override = 0;
-+				else {
-+					sc->sc_ackrate_override = 1;
-+					sc->sc_ackrate = val;
-+					ath_set_ack_bitrate(sc, sc->sc_ackrate);
-+				}
- 				break;
- 			case ATH_RP:
- 				ath_rp_record(sc,
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -681,6 +681,7 @@ struct ath_softc {
- 	unsigned int	sc_devstopped:1;	/* stopped due to of no tx bufs */
- 	unsigned int	sc_stagbeacons:1;	/* use staggered beacons */
- 	unsigned int	sc_dfswait:1;		/* waiting on channel for radar detect */
-+	unsigned int	sc_ackrate_override:1;	/* override ack rate */
- 	unsigned int	sc_ackrate:1;		/* send acks at high bitrate */
- 	unsigned int	sc_dfs_cac:1;		/* waiting on channel for radar detect */
- 	unsigned int	sc_hasintmit:1;		/* Interference mitigation */
diff --git a/package/madwifi/patches/349-reset.patch b/package/madwifi/patches/349-reset.patch
deleted file mode 100644
index 06e3fa86f7..0000000000
--- a/package/madwifi/patches/349-reset.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -8864,8 +8864,7 @@ ath_chan_set(struct ath_softc *sc, struc
- 		 * needed to do the reset with chanchange = AH_FALSE in order
- 		 * to receive traffic when peforming high velocity channel
- 		 * changes. */
--		if (!ath_hal_reset(ah, sc->sc_opmode, &hchan, AH_TRUE, &status)   ||
--		    !ath_hal_reset(ah, sc->sc_opmode, &hchan, AH_FALSE, &status)) {
-+		if (!ath_hal_reset(ah, sc->sc_opmode, &hchan, AH_TRUE, &status)) {
- 			EPRINTF(sc, "Unable to reset channel %u (%u MHz) "
- 				"flags 0x%x '%s' (HAL status %u)\n",
- 				ieee80211_chan2ieee(ic, chan), chan->ic_freq,
diff --git a/package/madwifi/patches/350-wisoc_softled.patch b/package/madwifi/patches/350-wisoc_softled.patch
deleted file mode 100644
index dae9f218df..0000000000
--- a/package/madwifi/patches/350-wisoc_softled.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ath/if_ath_ahb.c
-+++ b/ath/if_ath_ahb.c
-@@ -245,6 +245,8 @@ init_ath_wmac(u_int16_t devid, u_int16_t
- 	num_activesc++;
- 	/* Ready to process interrupts */
- 
-+	sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
-+	sc->aps_sc.sc_ledpin = config->board->sysLedGpio;
- 	sc->aps_sc.sc_invalid = 0;
- 	return 0;
- 
diff --git a/package/madwifi/patches/351-scanlist.patch b/package/madwifi/patches/351-scanlist.patch
deleted file mode 100644
index c11f28e39d..0000000000
--- a/package/madwifi/patches/351-scanlist.patch
+++ /dev/null
@@ -1,904 +0,0 @@
---- a/net80211/ieee80211_scan_sta.c
-+++ b/net80211/ieee80211_scan_sta.c
-@@ -317,147 +317,6 @@ found:
- #undef ISPROBE
- }
- 
--static struct ieee80211_channel *
--find11gchannel(struct ieee80211com *ic, int i, int freq)
--{
--	struct ieee80211_channel *c;
--	int j;
--
--	/*
--	 * The normal ordering in the channel list is b channel
--	 * immediately followed by g so optimize the search for
--	 * this.  We'll still do a full search just in case.
--	 */
--	for (j = i+1; j < ic->ic_nchans; j++) {
--		c = &ic->ic_channels[j];
--		if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
--			return c;
--	}
--	for (j = 0; j < i; j++) {
--		c = &ic->ic_channels[j];
--		if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
--			return c;
--	}
--	return NULL;
--}
--static const u_int chanflags[] = {
--	IEEE80211_CHAN_B,	/* IEEE80211_MODE_AUTO */
--	IEEE80211_CHAN_A,	/* IEEE80211_MODE_11A */
--	IEEE80211_CHAN_B,	/* IEEE80211_MODE_11B */
--	IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_11G */
--	IEEE80211_CHAN_FHSS,	/* IEEE80211_MODE_FH */
--	IEEE80211_CHAN_A,	/* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */
--	IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_TURBO_G */
--	IEEE80211_CHAN_ST,	/* IEEE80211_MODE_TURBO_STATIC_A */
--};
--
--static void
--add_channels(struct ieee80211com *ic,
--	struct ieee80211_scan_state *ss,
--	enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq)
--{
--	struct ieee80211_channel *c, *cg;
--	u_int modeflags;
--	int i;
--
--	KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode));
--	modeflags = chanflags[mode];
--	for (i = 0; i < nfreq; i++) {
--		c = ieee80211_find_channel(ic, freq[i], modeflags);
--		if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee))
--			continue;
--		if (mode == IEEE80211_MODE_AUTO) {
--			/*
--			 * XXX special-case 11b/g channels so we select
--			 *     the g channel if both are present.
--			 */
--			if (IEEE80211_IS_CHAN_B(c) &&
--			    (cg = find11gchannel(ic, i, c->ic_freq)) != NULL)
--				c = cg;
--		}
--		if (ss->ss_last >= IEEE80211_SCAN_MAX)
--			break;
--		ss->ss_chans[ss->ss_last++] = c;
--	}
--}
--
--static const u_int16_t rcl1[] =		/* 8 FCC channel: 52, 56, 60, 64, 36, 40, 44, 48 */
--{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 };
--static const u_int16_t rcl2[] =		/* 4 MKK channels: 34, 38, 42, 46 */
--{ 5170, 5190, 5210, 5230 };
--static const u_int16_t rcl3[] =		/* 2.4Ghz ch: 1,6,11,7,13 */
--{ 2412, 2437, 2462, 2442, 2472 };
--static const u_int16_t rcl4[] =		/* 5 FCC channel: 149, 153, 161, 165 */
--{ 5745, 5765, 5785, 5805, 5825 };
--static const u_int16_t rcl7[] =		/* 11 ETSI channel: 100,104,108,112,116,120,124,128,132,136,140 */
--{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 };
--static const u_int16_t rcl8[] =		/* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */
--{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 };
--static const u_int16_t rcl9[] =		/* 2.4Ghz ch: 14 */
--{ 2484 };
--static const u_int16_t rcl10[] =	/* Added Korean channels 2312-2372 */
--{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 };
--static const u_int16_t rcl11[] =	/* Added Japan channels in 4.9/5.0 spectrum */
--{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 };
--#ifdef ATH_TURBO_SCAN
--static const u_int16_t rcl5[] =		/* 3 static turbo channels */
--{ 5210, 5250, 5290 };
--static const u_int16_t rcl6[] =		/* 2 static turbo channels */
--{ 5760, 5800 };
--static const u_int16_t rcl6x[] =		/* 4 FCC3 turbo channels */
--{ 5540, 5580, 5620, 5660 };
--static const u_int16_t rcl12[] =		/* 2.4Ghz Turbo channel 6 */
--{ 2437 };
--static const u_int16_t rcl13[] =		/* dynamic Turbo channels */
--{ 5200, 5240, 5280, 5765, 5805 };
--#endif /* ATH_TURBO_SCAN */
--
--struct scanlist {
--	u_int16_t	mode;
--	u_int16_t	count;
--	const u_int16_t	*list;
--};
--
--#define	IEEE80211_MODE_TURBO_STATIC_A	IEEE80211_MODE_MAX
--#define	X(a)	.count = sizeof(a)/sizeof(a[0]), .list = a
--
--static const struct scanlist staScanTable[] = {
--	{ IEEE80211_MODE_11B,   		X(rcl3) },
--	{ IEEE80211_MODE_11A,   		X(rcl1) },
--	{ IEEE80211_MODE_11A,   		X(rcl2) },
--	{ IEEE80211_MODE_11B,   		X(rcl8) },
--	{ IEEE80211_MODE_11B,   		X(rcl9) },
--	{ IEEE80211_MODE_11A,   		X(rcl4) },
--#ifdef ATH_TURBO_SCAN
--	{ IEEE80211_MODE_TURBO_STATIC_A,	X(rcl5) },
--	{ IEEE80211_MODE_TURBO_STATIC_A,	X(rcl6) },
--	{ IEEE80211_MODE_TURBO_A,		X(rcl6x) },
--	{ IEEE80211_MODE_TURBO_A,		X(rcl13) },
--#endif /* ATH_TURBO_SCAN */
--	{ IEEE80211_MODE_11A,			X(rcl7) },
--	{ IEEE80211_MODE_11B,			X(rcl10) },
--	{ IEEE80211_MODE_11A,			X(rcl11) },
--#ifdef ATH_TURBO_SCAN
--	{ IEEE80211_MODE_TURBO_G,		X(rcl12) },
--#endif /* ATH_TURBO_SCAN */
--	{ .list = NULL }
--};
--
--#undef X
--
--static int
--checktable(const struct scanlist *scan, const struct ieee80211_channel *c)
--{
--	int i;
--
--	for (; scan->list != NULL; scan++) {
--		for (i = 0; i < scan->count; i++)
--			if (scan->list[i] == c->ic_freq)
--				return 1;
--	}
--	return 0;
--}
--
- /*
-  * Start a station-mode scan by populating the channel list.
-  */
-@@ -466,81 +325,14 @@ sta_start(struct ieee80211_scan_state *s
- {
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct sta_table *st = ss->ss_priv;
--	const struct scanlist *scan;
- 	enum ieee80211_phymode mode;
- 	struct ieee80211_channel *c;
- 	int i;
- 
- 	ss->ss_last = 0;
--	/*
--	 * Use the table of ordered channels to construct the list
--	 * of channels for scanning.  Any channels in the ordered
--	 * list not in the master list will be discarded.
--	 */
--	for (scan = staScanTable; scan->list != NULL; scan++) {
--		mode = scan->mode;
--		if (vap->iv_des_mode != IEEE80211_MODE_AUTO) {
--			/*
--			 * If a desired mode was specified, scan only 
--			 * channels that satisfy that constraint.
--			 */
--			if (vap->iv_des_mode != mode) {
--				/*
--				 * The scan table marks 2.4Ghz channels as b
--				 * so if the desired mode is 11g, then use
--				 * the 11b channel list but upgrade the mode.
--				 */
--				if (vap->iv_des_mode != IEEE80211_MODE_11G ||
--				    mode != IEEE80211_MODE_11B)
--					continue;
--				mode = IEEE80211_MODE_11G;	/* upgrade */
--			}
--		} else {
--			/*
--			 * This lets ieee80211_scan_add_channels
--			 * upgrade an 11b channel to 11g if available.
--			 */
--			if (mode == IEEE80211_MODE_11B)
--				mode = IEEE80211_MODE_AUTO;
--		}
--		/* XR does not operate on turbo channels */
--		if ((vap->iv_flags & IEEE80211_F_XR) &&
--		    (mode == IEEE80211_MODE_TURBO_A ||
--		     mode == IEEE80211_MODE_TURBO_G))
--			continue;
--		/*
--		 * Add the list of the channels; any that are not
--		 * in the master channel list will be discarded.
--		 */
--		add_channels(ic, ss, mode, scan->list, scan->count);
--	}
--
--	/*
--	 * Add the channels from the ic (from HAL) that are not present
--	 * in the staScanTable.
--	 */
--	for (i = 0; i < ic->ic_nchans; i++) {
--		c = &ic->ic_channels[i];
--		/*
--		 * scan dynamic turbo channels in normal mode.
--		 */
--		if (IEEE80211_IS_CHAN_DTURBO(c))
--			continue;
--		mode = ieee80211_chan2mode(c);
--		if (vap->iv_des_mode != IEEE80211_MODE_AUTO) {
--			/*
--			 * If a desired mode was specified, scan only 
--			 * channels that satisfy that constraint.
--			 */
--			if (vap->iv_des_mode != mode)
--				continue;
--
--		}
--		if (!checktable(staScanTable, c))
--			ss->ss_chans[ss->ss_last++] = c;
--	}
--
-+	ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode);
- 	ss->ss_next = 0;
-+
- 	/* XXX tunables */
- 	/* 
- 	 * The scanner will stay on station for ss_maxdwell ms (using a 
-@@ -749,17 +541,7 @@ match_bss(struct ieee80211vap *vap,
- 	fail = 0;
- 	if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, se->se_chan)))
- 		fail |= 0x01;
--	/*
--	 * NB: normally the desired mode is used to construct
--	 * the channel list, but it's possible for the scan
--	 * cache to include entries for stations outside this
--	 * list so we check the desired mode here to weed them
--	 * out.
--	 */
--	if (vap->iv_des_mode != IEEE80211_MODE_AUTO &&
--	    (se->se_chan->ic_flags & IEEE80211_CHAN_ALLTURBO) !=
--	    chanflags[vap->iv_des_mode])
--		fail |= 0x01;
-+
- 	if (vap->iv_opmode == IEEE80211_M_IBSS) {
- 		if ((se->se_capinfo & IEEE80211_CAPINFO_IBSS) == 0)
- 			fail |= 0x02;
-@@ -1168,78 +950,6 @@ static const struct ieee80211_scanner st
- 	.scan_default		= ieee80211_sta_join,
- };
- 
--/*
-- * Start an adhoc-mode scan by populating the channel list.
-- */
--static int
--adhoc_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
--{
--	struct ieee80211com *ic = vap->iv_ic;
--	struct sta_table *st = ss->ss_priv;
--	const struct scanlist *scan;
--	enum ieee80211_phymode mode;
--
--	ss->ss_last = 0;
--	/*
--	 * Use the table of ordered channels to construct the list
--	 * of channels for scanning.  Any channels in the ordered
--	 * list not in the master list will be discarded.
--	 */
--	for (scan = staScanTable; scan->list != NULL; scan++) {
--		mode = scan->mode;
--		if (vap->iv_des_mode != IEEE80211_MODE_AUTO) {
--			/*
--			 * If a desired mode was specified, scan only 
--			 * channels that satisfy that constraint.
--			 */
--			if (vap->iv_des_mode != mode) {
--				/*
--				 * The scan table marks 2.4Ghz channels as b
--				 * so if the desired mode is 11g, then use
--				 * the 11b channel list but upgrade the mode.
--				 */
--				if (vap->iv_des_mode != IEEE80211_MODE_11G ||
--				    mode != IEEE80211_MODE_11B)
--					continue;
--				mode = IEEE80211_MODE_11G;	/* upgrade */
--			}
--		} else {
--			/*
--			 * This lets ieee80211_scan_add_channels
--			 * upgrade an 11b channel to 11g if available.
--			 */
--			if (mode == IEEE80211_MODE_11B)
--				mode = IEEE80211_MODE_AUTO;
--		}
--		/* XR does not operate on turbo channels */
--		if ((vap->iv_flags & IEEE80211_F_XR) &&
--		    (mode == IEEE80211_MODE_TURBO_A ||
--		     mode == IEEE80211_MODE_TURBO_G))
--			continue;
--		/*
--		 * Add the list of the channels; any that are not
--		 * in the master channel list will be discarded.
--		 */
--		add_channels(ic, ss, mode, scan->list, scan->count);
--	}
--	ss->ss_next = 0;
--	/* XXX tunables */
--	ss->ss_mindwell = msecs_to_jiffies(200);	/* 200ms */
--	ss->ss_maxdwell = msecs_to_jiffies(200);	/* 200ms */
--
--#ifdef IEEE80211_DEBUG
--	if (ieee80211_msg_scan(vap)) {
--		printk("%s: scan set ", vap->iv_dev->name);
--		ieee80211_scan_dump_channels(ss);
--		printk(" dwell min %ld max %ld\n",
--			ss->ss_mindwell, ss->ss_maxdwell);
--	}
--#endif /* IEEE80211_DEBUG */
--
--	st->st_newscan = 1;
--
--	return 0;
--}
- 
- /*
-  * Select a channel to start an adhoc network on.
-@@ -1405,7 +1115,7 @@ static const struct ieee80211_scanner ad
- 	.scan_name		= "default",
- 	.scan_attach		= sta_attach,
- 	.scan_detach		= sta_detach,
--	.scan_start		= adhoc_start,
-+	.scan_start		= sta_start,
- 	.scan_restart		= sta_restart,
- 	.scan_cancel		= sta_cancel,
- 	.scan_end		= adhoc_pick_bss,
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -278,6 +278,11 @@ ieee80211_ifattach(struct ieee80211com *
- 			("channel with bogus ieee number %u", c->ic_ieee));
- 		setbit(ic->ic_chan_avail, c->ic_ieee);
- 
-+		if (c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT)
-+			c->ic_scanflags |= IEEE80211_NOSCAN_SET;
-+		else
-+			c->ic_scanflags &= ~IEEE80211_NOSCAN_SET;
-+
- 		/* Identify mode capabilities. */
- 		if (IEEE80211_IS_CHAN_A(c))
- 			ic->ic_modecaps |= 1 << IEEE80211_MODE_11A;
-@@ -1447,10 +1452,6 @@ ieee80211_media_change(struct net_device
- 		vap->iv_fixed_rate = newrate;		/* fixed TX rate */
- 		error = -ENETRESET;
- 	}
--	if (vap->iv_des_mode != newmode) {
--		vap->iv_des_mode = newmode;		/* desired PHY mode */
--		error = -ENETRESET;
--	}
- 	return error;
- }
- EXPORT_SYMBOL(ieee80211_media_change);
---- a/net80211/_ieee80211.h
-+++ b/net80211/_ieee80211.h
-@@ -132,6 +132,11 @@ enum ieee80211_scanmode {
- 	IEEE80211_SCAN_FIRST	= 2,	/* take first suitable candidate */
- };
- 
-+enum ieee80211_scanflags {
-+	IEEE80211_NOSCAN_DEFAULT = (1 << 0),
-+	IEEE80211_NOSCAN_SET     = (1 << 1),
-+};
-+
- /*
-  * Channels are specified by frequency and attributes.
-  */
-@@ -142,6 +147,7 @@ struct ieee80211_channel {
- 	int8_t ic_maxregpower;	/* maximum regulatory tx power in dBm */
- 	int8_t ic_maxpower;	/* maximum tx power in dBm */
- 	int8_t ic_minpower;	/* minimum tx power in dBm */
-+	u_int8_t ic_scanflags;
- };
- 
- #define	IEEE80211_CHAN_MAX	255
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -555,6 +555,7 @@ struct ieee80211req_scan_result {
- #define	IEEE80211_IOCTL_WDSADDMAC	(SIOCIWFIRSTPRIV+26)
- #define	IEEE80211_IOCTL_WDSDELMAC	(SIOCIWFIRSTPRIV+28)
- #define	IEEE80211_IOCTL_KICKMAC		(SIOCIWFIRSTPRIV+30)
-+#define	IEEE80211_IOCTL_SETSCANLIST	(SIOCIWFIRSTPRIV+31)
- 
- enum {
- 	IEEE80211_WMMPARAMS_CWMIN       = 1,
---- a/net80211/ieee80211_scan_ap.c
-+++ b/net80211/ieee80211_scan_ap.c
-@@ -105,11 +105,6 @@ struct scan_entry {
- };
- 
- struct ap_state {
--	unsigned int as_vap_desired_mode;       /* Used for channel selection, 
--						 * vap->iv_des_mode */
--	unsigned int as_required_mode;          /* Used for channel selection, 
--						 * filtered version of 
--						 * as_vap_desired_mode */
- 	int as_maxrssi[IEEE80211_CHAN_MAX]; 	/* Used for channel selection */
- 
- 	/* These fields are just for scan caching for returning responses to
-@@ -129,131 +124,7 @@ struct ap_state {
- 
- static int ap_flush(struct ieee80211_scan_state *);
- static void action_tasklet(IEEE80211_TQUEUE_ARG);
--static struct ieee80211_channel *find11gchannel(struct ieee80211com *ic, 
--		int i, int freq);
- 
--static const u_int chanflags[] = {
--	IEEE80211_CHAN_B,	/* IEEE80211_MODE_AUTO */
--	IEEE80211_CHAN_A,	/* IEEE80211_MODE_11A */
--	IEEE80211_CHAN_B,	/* IEEE80211_MODE_11B */
--	IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_11G */
--	IEEE80211_CHAN_FHSS,	/* IEEE80211_MODE_FH */
--	IEEE80211_CHAN_A,	/* IEEE80211_MODE_TURBO_A */ /* for turbo mode 
--							      * look for AP in 
--							      * normal channel 
--							      */
--	IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_TURBO_G */
--	IEEE80211_CHAN_ST,	/* IEEE80211_MODE_TURBO_STATIC_A */
--};
--
--static const u_int16_t rcl1[] =		/* 8 FCC channel: 52, 56, 60, 64, 
--					 *                36, 40, 44, 48 */
--{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 };
--static const u_int16_t rcl2[] =		/* 4 MKK channels: 34, 38, 42, 46 */
--{ 5170, 5190, 5210, 5230 };
--static const u_int16_t rcl3[] =		/* 2.4Ghz ch: 1,6,11,7,13 */
--{ 2412, 2437, 2462, 2442, 2472 };
--static const u_int16_t rcl4[] =		/* 5 FCC channel: 149, 153, 161, 165 */
--{ 5745, 5765, 5785, 5805, 5825 };
--static const u_int16_t rcl7[] =		/* 11 ETSI channel: 100, 104, 108, 112,
--					 *                  116, 120, 124, 128, 
--					 *                  132, 136, 140 */
--{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 };
--static const u_int16_t rcl8[] =		/* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */
--{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 };
--static const u_int16_t rcl9[] =		/* 2.4Ghz ch: 14 */
--{ 2484 };
--static const u_int16_t rcl10[] =	/* Added Korean channels 2312-2372 */
--{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 };
--static const u_int16_t rcl11[] =	/* Added Japan channels in 4.9/5.0 spectrum */
--{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 };
--#ifdef ATH_TURBO_SCAN
--static const u_int16_t rcl5[] =		/* 3 static turbo channels */
--{ 5210, 5250, 5290 };
--static const u_int16_t rcl6[] =		/* 2 static turbo channels */
--{ 5760, 5800 };
--static const u_int16_t rcl6x[] =		/* 4 FCC3 turbo channels */
--{ 5540, 5580, 5620, 5660 };
--static const u_int16_t rcl12[] =		/* 2.4Ghz Turbo channel 6 */
--{ 2437 };
--static const u_int16_t rcl13[] =		/* dynamic Turbo channels */
--{ 5200, 5240, 5280, 5765, 5805 };
--#endif /* ATH_TURBO_SCAN */
--
--struct scanlist {
--	u_int16_t	mode;
--	u_int16_t	count;
--	const u_int16_t	*list;
--};
--
--#define	IEEE80211_MODE_TURBO_STATIC_A	IEEE80211_MODE_MAX
--#define	X(a)	.count = ARRAY_SIZE(a), .list = a
--
--static const struct scanlist staScanTable[] = {
--	{ IEEE80211_MODE_11B,   		X(rcl3)  },
--	{ IEEE80211_MODE_11A,   		X(rcl1)  },
--	{ IEEE80211_MODE_11A,   		X(rcl2)  },
--	{ IEEE80211_MODE_11B,   		X(rcl8)  },
--	{ IEEE80211_MODE_11B,   		X(rcl9)  },
--	{ IEEE80211_MODE_11A,   		X(rcl4)  },
--#ifdef ATH_TURBO_SCAN
--	{ IEEE80211_MODE_TURBO_STATIC_A,	X(rcl5)  },
--	{ IEEE80211_MODE_TURBO_STATIC_A,	X(rcl6)  },
--	{ IEEE80211_MODE_TURBO_A,		X(rcl6x) },
--	{ IEEE80211_MODE_TURBO_A,		X(rcl13) },
--#endif /* ATH_TURBO_SCAN */
--	{ IEEE80211_MODE_11A,			X(rcl7)  },
--	{ IEEE80211_MODE_11B,			X(rcl10) },
--	{ IEEE80211_MODE_11A,			X(rcl11) },
--#ifdef ATH_TURBO_SCAN
--	{ IEEE80211_MODE_TURBO_G,		X(rcl12) },
--#endif /* ATH_TURBO_SCAN */
--	{ .list = NULL }
--};
--
--#undef X
--/* This function must be invoked with locks acquired */
--static void
--add_channels(struct ieee80211com *ic,
--	struct ieee80211_scan_state *ss,
--	enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq)
--{
--	struct ieee80211_channel *c, *cg;
--	u_int modeflags;
--	int i;
--
--	KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode));
--	modeflags = chanflags[mode];
--	for (i = 0; i < nfreq; i++) {
--		c = ieee80211_find_channel(ic, freq[i], modeflags);
--		if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee))
--			continue;
--		if (mode == IEEE80211_MODE_AUTO) {
--			/* XXX special-case 11b/g channels so we select
--			 *     the g channel if both are present. */
--			if (IEEE80211_IS_CHAN_B(c) &&
--			    (cg = find11gchannel(ic, i, c->ic_freq)) != NULL)
--				c = cg;
--		}
--		if (ss->ss_last >= IEEE80211_SCAN_MAX)
--			break;
--		ss->ss_chans[ss->ss_last++] = c;
--	}
--}
--
--/* This function must be invoked with locks acquired */
--static int
--checktable(const struct scanlist *scan, const struct ieee80211_channel *c)
--{
--	int i;
--
--	for (; scan->list != NULL; scan++) {
--		for (i = 0; i < scan->count; i++)
--			if (scan->list[i] == c->ic_freq)
--				return 1;
--	}
--	return 0;
--}
- 
- /*
-  * Attach prior to any scanning work.
-@@ -327,29 +198,6 @@ saveie(u_int8_t **iep, const u_int8_t *i
- 		ieee80211_saveie(iep, ie);
- }
- 
--/* This function must be invoked with locks acquired */
--static struct ieee80211_channel *
--find11gchannel(struct ieee80211com *ic, int i, int freq)
--{
--	struct ieee80211_channel *c;
--	int j;
--
--	/* The normal ordering in the channel list is b channel
--	 * immediately followed by g so optimize the search for
--	 * this.  We'll still do a full search just in case. */
--	for (j = i + 1; j < ic->ic_nchans; j++) {
--		c = &ic->ic_channels[j];
--		if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c))
--			return c;
--	}
--	for (j = 0; j < i; j++) {
--		c = &ic->ic_channels[j];
--		if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c))
--			return c;
--	}
--	return NULL;
--}
--
- /*
-  * Start an ap scan by populating the channel list.
-  */
-@@ -358,90 +206,15 @@ ap_start(struct ieee80211_scan_state *ss
- {
- 	struct ap_state *as 	    = ss->ss_priv;
- 	struct ieee80211com *ic     = NULL;
--	const struct scanlist *sl   = NULL;
--	struct ieee80211_channel *c = NULL;
- 	int i;
- 	unsigned int mode = 0;
- 
- 	SCAN_AP_LOCK_IRQ(as);
- 	ic = vap->iv_ic;
- 	/* Determine mode flags to match, or leave zero for auto mode */
--	as->as_vap_desired_mode = vap->iv_des_mode;
--	as->as_required_mode    = 0;
--	if (as->as_vap_desired_mode != IEEE80211_MODE_AUTO) {
--		as->as_required_mode = chanflags[as->as_vap_desired_mode];
--		if ((vap->iv_ath_cap & IEEE80211_ATHC_TURBOP) && 
--		    (as->as_required_mode != IEEE80211_CHAN_ST)) {
--			/* Fixup for dynamic turbo flags */
--			if (as->as_vap_desired_mode == IEEE80211_MODE_11G)
--				as->as_required_mode = IEEE80211_CHAN_108G;
--			else
--				as->as_required_mode = IEEE80211_CHAN_108A;
--		}
--	}
--
- 	ss->ss_last = 0;
--	/* Use the table of ordered channels to construct the list
--	 * of channels for scanning.  Any channels in the ordered
--	 * list not in the master list will be discarded. */
--	for (sl = staScanTable; sl->list != NULL; sl++) {
--		mode = sl->mode;
--
--		/* The scan table marks 2.4Ghz channels as b
--		 * so if the desired mode is 11g, then use
--		 * the 11b channel list but upgrade the mode. */
--		if (as->as_vap_desired_mode &&
--		    (as->as_vap_desired_mode != mode) && 
--		    (as->as_vap_desired_mode == IEEE80211_MODE_11G) && 
--		    (mode == IEEE80211_MODE_11B))
--			mode = IEEE80211_MODE_11G;
--
--		/* If we are in "AUTO" mode, upgrade the mode to auto. 
--		 * This lets add_channels upgrade an 11b channel to 
--		 * 11g if available. */
--		if (!as->as_vap_desired_mode && (mode == IEEE80211_MODE_11B))
--			mode = IEEE80211_MODE_AUTO;
--
--		/* Add the list of the channels; any that are not
--		 * in the master channel list will be discarded. */
--		add_channels(ic, ss, mode, sl->list, sl->count);
--	}
--
--	/* Add the channels from the ic (from HAL) that are not present
--	 * in the staScanTable, assuming they pass the sanity checks... */
--	for (i = 0; i < ic->ic_nchans; i++) {
--		c = &ic->ic_channels[i];
--
--		/* XR is not supported on turbo channels */
--		if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_flags & IEEE80211_F_XR)
--			continue;
--
--		/* Dynamic channels are scanned in base mode */
--		if (!as->as_required_mode && !IEEE80211_IS_CHAN_ST(c))
--			continue;
--
--		/* Use any 11g channel instead of 11b one. */
--		if (vap->iv_des_mode == IEEE80211_MODE_AUTO && 
--		    IEEE80211_IS_CHAN_B(c) &&
--		    find11gchannel(ic, i, c->ic_freq))
--			continue;
--
--		/* Do not add channels already put into the scan list by the
--		 * scan table - these have already been filtered by mode
--		 * and for whether they are in the active channel list. */
--		if (checktable(staScanTable, c))
--			continue;
--
--		/* Make sure the channel is active */
--		if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee))
--			continue;
-+	ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode);
- 
--		/* Don't overrun */
--		if (ss->ss_last >= IEEE80211_SCAN_MAX)
--			break;
--
--		ss->ss_chans[ss->ss_last++] = c;
--	}
- 	ss->ss_next = 0;
- 	/* XXX tunables */
- 	ss->ss_mindwell = msecs_to_jiffies(200);	/* 200ms */
-@@ -761,18 +534,6 @@ pick_channel(struct ieee80211_scan_state
- 		if (IEEE80211_IS_CHAN_RADAR(c->chan))
- 			continue;
- 
--		/* Do not select 802.11a ST if mode is specified and is not 
--		 * 802.11a ST */
--		if (as->as_required_mode &&
--		    IEEE80211_IS_CHAN_STURBO(c->chan) &&
--		    (as->as_vap_desired_mode != IEEE80211_MODE_TURBO_STATIC_A))
--			continue;
--
--		/* Verify mode matches any fixed mode specified */
--		if((c->chan->ic_flags & as->as_required_mode) != 
--				as->as_required_mode)
--			continue;
--
- 		if ((ic->ic_bsschan != NULL) &&
- 			(ic->ic_bsschan != IEEE80211_CHAN_ANYC)) {
- 
---- a/net80211/ieee80211_scan.c
-+++ b/net80211/ieee80211_scan.c
-@@ -958,6 +958,80 @@ ieee80211_scan_flush(struct ieee80211com
- 	}
- }
- 
-+static const u_int chanflags[] = {
-+	0,	/* IEEE80211_MODE_AUTO */
-+	IEEE80211_CHAN_A,	/* IEEE80211_MODE_11A */
-+	IEEE80211_CHAN_B,	/* IEEE80211_MODE_11B */
-+	IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_11G */
-+	IEEE80211_CHAN_FHSS,	/* IEEE80211_MODE_FH */
-+	IEEE80211_CHAN_A,	/* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */
-+	IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_TURBO_G */
-+	IEEE80211_CHAN_ST,	/* IEEE80211_MODE_TURBO_STATIC_A */
-+};
-+
-+static struct ieee80211_channel *
-+find11gchannel(struct ieee80211com *ic, int i, int freq)
-+{
-+	struct ieee80211_channel *c;
-+	int j;
-+
-+	/*
-+	 * The normal ordering in the channel list is b channel
-+	 * immediately followed by g so optimize the search for
-+	 * this.  We'll still do a full search just in case.
-+	 */
-+	for (j = i+1; j < ic->ic_nchans; j++) {
-+		c = &ic->ic_channels[j];
-+		if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
-+			return c;
-+	}
-+	for (j = 0; j < i; j++) {
-+		c = &ic->ic_channels[j];
-+		if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
-+			return c;
-+	}
-+	return NULL;
-+}
-+
-+
-+void
-+ieee80211_scan_add_channels(struct ieee80211com *ic,
-+	struct ieee80211_scan_state *ss,
-+	enum ieee80211_phymode mode)
-+{
-+	struct ieee80211_channel *c, *cg;
-+	u_int modeflags;
-+	int i;
-+
-+	KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode));
-+	modeflags = chanflags[mode];
-+	for (i = 0; i < ic->ic_nchans; i++) {
-+		c = &ic->ic_channels[i];
-+		if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee))
-+			continue;
-+		if (c->ic_scanflags & IEEE80211_NOSCAN_SET)
-+			continue;
-+		if (modeflags &&
-+			((c->ic_flags & IEEE80211_CHAN_ALLTURBO) !=
-+			 (modeflags & IEEE80211_CHAN_ALLTURBO)))
-+			continue;
-+		if (mode == IEEE80211_MODE_AUTO) {
-+			/*
-+			 * XXX special-case 11b/g channels so we select
-+			 *     the g channel if both are present.
-+			 */
-+			if (IEEE80211_IS_CHAN_B(c) &&
-+			    (cg = find11gchannel(ic, i, c->ic_freq)) != NULL)
-+				continue;
-+		}
-+		if (ss->ss_last >= IEEE80211_SCAN_MAX)
-+			break;
-+		ss->ss_chans[ss->ss_last++] = c;
-+	}
-+}
-+EXPORT_SYMBOL(ieee80211_scan_add_channels);
-+
-+
- /*
-  * Execute radar channel change. This is called when a radar/dfs
-  * signal is detected.  AP mode only.  Return 1 on success, 0 on
---- a/net80211/ieee80211_scan.h
-+++ b/net80211/ieee80211_scan.h
-@@ -219,4 +219,7 @@ void ieee80211_scanner_register(enum iee
- void ieee80211_scanner_unregister(enum ieee80211_opmode,
- 	const struct ieee80211_scanner *);
- void ieee80211_scanner_unregister_all(const struct ieee80211_scanner *);
-+void ieee80211_scan_add_channels(struct ieee80211com *ic,
-+	struct ieee80211_scan_state *ss,
-+	enum ieee80211_phymode mode);
- #endif /* _NET80211_IEEE80211_SCAN_H_ */
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -3873,6 +3873,106 @@ ieee80211_ioctl_kickmac(struct net_devic
- 	return ieee80211_ioctl_setmlme(dev, info, w, (char *)&mlme);
- }
- 
-+static inline void setflag(struct ieee80211_channel *c, int flag)
-+{
-+	if (flag)
-+		c->ic_scanflags |= IEEE80211_NOSCAN_SET;
-+	else
-+		c->ic_scanflags &= ~IEEE80211_NOSCAN_SET;
-+}
-+
-+static void setscanflag(struct ieee80211com *ic, int min, int max, int set)
-+{
-+	int i;
-+
-+	for (i = 0; i < ic->ic_nchans; i++) {
-+		struct ieee80211_channel *c = &ic->ic_channels[i];
-+
-+		if (min == -1) {
-+			if (!(c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT))
-+				setflag(c, set);
-+		} else if ((c->ic_freq >= min) && (c->ic_freq <= max)) {
-+			setflag(c, set);
-+		}
-+	}
-+}
-+
-+static int
-+ieee80211_ioctl_setscanlist(struct net_device *dev,
-+	struct iw_request_info *info,
-+	struct iw_point *data, char *extra)
-+{
-+	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211com *ic = vap->iv_ic;
-+	char *s, *next;
-+	int val = 1;
-+
-+	if (data->length <= 0)
-+		return -EINVAL;
-+
-+	s = kmalloc(data->length + 1, GFP_KERNEL);
-+	if (!s)
-+		return -ENOMEM;
-+
-+	memset(s, 0, data->length + 1);
-+	if (copy_from_user(s, data->pointer, data->length))
-+		return -EFAULT;
-+
-+	s[data->length - 1] = '\0';		/* ensure null termination */
-+
-+	switch(*s) {
-+		case '-':
-+			val = 1;
-+			break;
-+		case '+':
-+			val = 0;
-+			break;
-+		default:
-+			goto error;
-+	}
-+	s++;
-+	next = s;
-+	do {
-+		next = strchr(s, ',');
-+		if (next) {
-+			*next = 0;
-+			next++;
-+		}
-+		if (!strcmp(s, "ALL")) {
-+			setscanflag(ic, 0, 10000, val);
-+		} else if (!strcmp(s, "REG")) {
-+			setscanflag(ic, -1, -1, val);
-+		} else {
-+			int min, max;
-+			char *n, *end = NULL;
-+
-+			n = strchr(s, '-');
-+			if (n) {
-+				*n = 0;
-+				n++;
-+			}
-+			min = simple_strtoul(s, &end, 10);
-+			if (end && *end)
-+				goto error;
-+			if (n) {
-+				max = simple_strtoul(n, &end, 10);
-+				if (end && *end)
-+					goto error;
-+			} else {
-+				max = min;
-+			}
-+			setscanflag(ic, min, max, val);
-+		}
-+		s = next;
-+	} while (next);
-+	return 0;
-+
-+error:
-+	if (s)
-+		kfree(s);
-+	return -EINVAL;
-+}
-+
- static int
- ieee80211_ioctl_addmac(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
-@@ -5656,6 +5756,8 @@ static const struct iw_priv_args ieee802
- 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"},
- 	{IEEE80211_PARAM_MINRATE,
- 	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"},
-+	{ IEEE80211_IOCTL_SETSCANLIST,
-+	 IW_PRIV_TYPE_CHAR | 255, 0, "setscanlist"},
- 
- #ifdef ATH_REVERSE_ENGINEERING
- 	/*
-@@ -5753,6 +5855,7 @@ static const iw_handler ieee80211_priv_h
- 	set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac),
- 	set_priv(IEEE80211_IOCTL_WDSDELMAC, ieee80211_ioctl_wdsdelmac),
- 	set_priv(IEEE80211_IOCTL_KICKMAC, ieee80211_ioctl_kickmac),
-+	set_priv(IEEE80211_IOCTL_SETSCANLIST, ieee80211_ioctl_setscanlist),
- #ifdef ATH_REVERSE_ENGINEERING
- 	set_priv(IEEE80211_IOCTL_READREG, ieee80211_ioctl_readreg),
- 	set_priv(IEEE80211_IOCTL_WRITEREG, ieee80211_ioctl_writereg),
diff --git a/package/madwifi/patches/352-ani_fix.patch b/package/madwifi/patches/352-ani_fix.patch
deleted file mode 100644
index 938d11c623..0000000000
--- a/package/madwifi/patches/352-ani_fix.patch
+++ /dev/null
@@ -1,265 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -1014,9 +1014,7 @@ ath_attach(u_int16_t devid, struct net_d
- 	 */
- 	sc->sc_hasveol = ath_hal_hasveol(ah);
- 
--	/* Interference mitigation/ambient noise immunity (ANI).
--	 * In modes other than HAL_M_STA, it causes receive sensitivity
--	 * problems for OFDM. */
-+	/* Interference mitigation/ambient noise immunity (ANI). */
- 	sc->sc_hasintmit = ath_hal_hasintmit(ah);
- 
- 	/* get mac address from hardware */
-@@ -1144,6 +1142,11 @@ ath_attach(u_int16_t devid, struct net_d
- 	sc->sc_rp_lasttsf	= 0;
- 	sc->sc_last_tsf		= 0;
- 
-+	/* set all 3 to auto */
-+	sc->sc_intmit = -1;
-+	sc->sc_noise_immunity = -1;
-+	sc->sc_ofdm_weak_det = -1;
-+
- 	return 0;
- bad3:
- 	ieee80211_ifdetach(ic);
-@@ -2428,6 +2431,43 @@ ath_chan2flags(struct ieee80211_channel
- 	return flags;
- }
- 
-+static int ath_setintmit(struct ath_softc *sc)
-+{
-+	struct ath_hal *ah = sc->sc_ah;
-+	int ret;
-+	int val;
-+
-+	if (!sc->sc_hasintmit)
-+		return 0;
-+
-+	switch(sc->sc_intmit) {
-+		case -1:
-+			if (sc->sc_opmode != IEEE80211_M_MONITOR)
-+				val = 1;
-+			else
-+				val = 0;
-+			break;
-+		case 0: /* disabled */
-+		case 1: /* enabled */
-+			val = sc->sc_intmit;
-+			break;
-+		default:
-+			return 0;
-+	}
-+	ret = ath_hal_setintmit(ah, val);
-+	if (val)
-+		goto done;
-+
-+	/* manual settings */
-+	if ((sc->sc_noise_immunity >= 0) && (sc->sc_noise_immunity <= 5))
-+		ath_hal_setcapability(ah, HAL_CAP_INTMIT, 2, sc->sc_noise_immunity, NULL);
-+	if ((sc->sc_ofdm_weak_det == 0) || (sc->sc_ofdm_weak_det == 1))
-+		ath_hal_setcapability(ah, HAL_CAP_INTMIT, 3, sc->sc_ofdm_weak_det, NULL);
-+
-+done:
-+	return ret;
-+}
-+
- /*
-  * Context: process context
-  */
-@@ -2493,8 +2533,7 @@ ath_init(struct net_device *dev)
- 	if (sc->sc_softled)
- 		ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
- 
--	if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
--		ath_hal_setintmit(ah, 0);
-+	ath_setintmit(sc);
- 
- 	/*
- 	 * This is needed only to setup initial state
-@@ -2530,7 +2569,7 @@ ath_init(struct net_device *dev)
- 	 * Enable MIB interrupts when there are hardware phy counters.
- 	 * Note we only do this (at the moment) for station mode.
- 	 */
--	if (sc->sc_needmib && ic->ic_opmode == IEEE80211_M_STA)
-+	if (sc->sc_needmib && ath_hal_getintmit(ah, NULL))
- 		sc->sc_imask |= HAL_INT_MIB;
- 	ath_hal_intrset(ah, sc->sc_imask);
- 
-@@ -2787,9 +2826,7 @@ ath_reset(struct net_device *dev)
- 		EPRINTF(sc, "Unable to reset hardware: '%s' (HAL status %u)\n",
- 			ath_get_hal_status_desc(status), status);
- 
--	if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
--		ath_hal_setintmit(ah, 0);
--
-+	ath_setintmit(sc);
- 	ath_update_txpow(sc);		/* update tx power state */
- 	ath_radar_update(sc);
- 	ath_setdefantenna(sc, sc->sc_defant);
-@@ -4174,6 +4211,8 @@ ath_calcrxfilter(struct ath_softc *sc)
- 	if (sc->sc_nmonvaps > 0)
- 		rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
- 			  HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM);
-+	if (sc->sc_hasintmit && !sc->sc_needmib && ath_hal_getintmit(ah, NULL))
-+		rfilt |= HAL_RX_FILTER_PHYERR;
- 	if (sc->sc_curchan.privFlags & CHANNEL_DFS)
- 		rfilt |= (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR);
- 	return rfilt;
-@@ -6526,9 +6565,6 @@ process_rx_again:
- 			rs->rs_rssi = 0;
- 
- 		len = rs->rs_datalen;
--		/* DMA sync. dies spectacularly if len == 0 */
--		if (len == 0)
--			goto rx_next;
- 
- 		if (rs->rs_more) {
- 			/*
-@@ -8876,9 +8912,7 @@ ath_chan_set(struct ath_softc *sc, struc
- 		if (sc->sc_softled)
- 			ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
- 
--		if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
--			ath_hal_setintmit(ah, 0);
--
-+		ath_setintmit(sc);
- 		sc->sc_curchan = hchan;
- 		ath_update_txpow(sc);		/* update tx power state */
- 		ath_radar_update(sc);
-@@ -10655,9 +10689,54 @@ enum {
- 	ATH_RP_IGNORED 		= 24,
- 	ATH_RADAR_IGNORED       = 25,
- 	ATH_MAXVAPS  		= 26,
-+	ATH_INTMIT			= 27,
-+	ATH_NOISE_IMMUNITY	= 28,
-+	ATH_OFDM_WEAK_DET	= 29
- };
- 
- static int
-+ath_sysctl_set_intmit(struct ath_softc *sc, long ctl, u_int val)
-+{
-+	int ret;
-+
-+	switch(ctl) {
-+	case ATH_INTMIT:
-+		sc->sc_intmit = val;
-+		break;
-+	case ATH_NOISE_IMMUNITY:
-+		sc->sc_noise_immunity = val;
-+		break;
-+	case ATH_OFDM_WEAK_DET:
-+		sc->sc_ofdm_weak_det = val;
-+		break;
-+	default:
-+		return -EINVAL;
-+	}
-+	ret = ath_setintmit(sc);
-+	ath_calcrxfilter(sc);
-+	return ret;
-+}
-+
-+static int
-+ath_sysctl_get_intmit(struct ath_softc *sc, long ctl, u_int *val)
-+{
-+	struct ath_hal *ah = sc->sc_ah;
-+
-+	switch(ctl) {
-+	case ATH_INTMIT:
-+		*val = (ath_hal_getcapability(ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK);
-+		break;
-+	case ATH_NOISE_IMMUNITY:
-+		return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 2, val);
-+	case ATH_OFDM_WEAK_DET:
-+		return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 3, val);
-+	default:
-+		return -EINVAL;
-+	}
-+	return 0;
-+}
-+
-+static int
- ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
- {
- 	struct ath_softc *sc = ctl->extra1;
-@@ -10843,6 +10922,11 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 			case ATH_RADAR_IGNORED:
- 				sc->sc_radar_ignored = val;
- 				break;
-+			case ATH_INTMIT:
-+			case ATH_NOISE_IMMUNITY:
-+			case ATH_OFDM_WEAK_DET:
-+				ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val);
-+				break;
- 			default:
- 				ret = -EINVAL;
- 				break;
-@@ -10909,6 +10993,11 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 		case ATH_RADAR_IGNORED:
- 			val = sc->sc_radar_ignored;
- 			break;
-+		case ATH_INTMIT:
-+		case ATH_NOISE_IMMUNITY:
-+		case ATH_OFDM_WEAK_DET:
-+			ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val);
-+			break;
- 		default:
- 			ret = -EINVAL;
- 			break;
-@@ -11086,6 +11175,24 @@ static const ctl_table ath_sysctl_templa
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RADAR_IGNORED,
- 	},
-+	{ .ctl_name	= CTL_AUTO,
-+	  .procname     = "intmit",
-+	  .mode         = 0644,
-+	  .proc_handler = ath_sysctl_halparam,
-+	  .extra2	= (void *)ATH_INTMIT,
-+	},
-+	{ .ctl_name	= CTL_AUTO,
-+	  .procname     = "noise_immunity",
-+	  .mode         = 0644,
-+	  .proc_handler = ath_sysctl_halparam,
-+	  .extra2	= (void *)ATH_NOISE_IMMUNITY,
-+	},
-+	{ .ctl_name	= CTL_AUTO,
-+	  .procname     = "ofdm_weak_det",
-+	  .mode         = 0644,
-+	  .proc_handler = ath_sysctl_halparam,
-+	  .extra2	= (void *)ATH_OFDM_WEAK_DET,
-+	},
- 	{ 0 }
- };
- 
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -693,6 +693,10 @@ struct ath_softc {
- 	unsigned int sc_txcont_power; /* Continuous transmit power in 0.5dBm units */
- 	unsigned int sc_txcont_rate;  /* Continuous transmit rate in Mbps */
- 
-+	int8_t sc_intmit; /* Interference mitigation enabled, -1 = auto, based on mode, 0/1 = off/on */
-+	int8_t sc_noise_immunity; /* Noise immunity level, 0-4, -1 == auto) */
-+	int8_t sc_ofdm_weak_det; /* OFDM weak frames detection, -1 == auto */
-+
- 	/* rate tables */
- 	const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
- 	const HAL_RATE_TABLE *sc_currates;	/* current rate table */
---- a/ath/if_ath_hal.h
-+++ b/ath/if_ath_hal.h
-@@ -67,14 +67,14 @@ static inline HAL_POWER_MODE ath_hal_get
- 
- static inline HAL_BOOL ath_hal_getdiagstate(struct ath_hal *ah, int request,
- 					    const void *args, u_int32_t argsize,
--					    void **result,
-+					    void *result,
- 					    u_int32_t *resultsize)
- {
- 	HAL_BOOL ret;
- 	ATH_HAL_LOCK_IRQ(ah->ah_sc);
- 	ath_hal_set_function(__func__);
- 	ret =
--	    ah->ah_getDiagState(ah, request, args, argsize, *result,
-+	    ah->ah_getDiagState(ah, request, args, argsize, result,
- 				resultsize);
- 	ath_hal_set_function(NULL);
- 	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
diff --git a/package/madwifi/patches/353-devid.patch b/package/madwifi/patches/353-devid.patch
deleted file mode 100644
index ee149ff0c2..0000000000
--- a/package/madwifi/patches/353-devid.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/ath/if_ath_pci.c
-+++ b/ath/if_ath_pci.c
-@@ -114,11 +114,15 @@ static struct pci_device_id ath_pci_id_t
- 	{ 0x168c, 0x0023, PCI_ANY_ID, PCI_ANY_ID },
- 	{ 0x168c, 0x0024, PCI_ANY_ID, PCI_ANY_ID },
- 	{ 0x168c, 0x9013, PCI_ANY_ID, PCI_ANY_ID }, /* sonicwall */
-+	{ 0x168c, 0xff16, PCI_ANY_ID, PCI_ANY_ID },
-+	{ 0x168c, 0xff1a, PCI_ANY_ID, PCI_ANY_ID },
- 	{ 0 }
- };
- 
- static u16 ath_devidmap[][2] = {
--	{ 0x9013, 0x0013 }
-+	{ 0x9013, 0x0013 },
-+	{ 0xff16, 0x0013 },
-+	{ 0xff1a, 0x001a }
- };
- 
- static int
diff --git a/package/madwifi/patches/354-lantiq_eeprom.patch b/package/madwifi/patches/354-lantiq_eeprom.patch
deleted file mode 100644
index 59036b1b4b..0000000000
--- a/package/madwifi/patches/354-lantiq_eeprom.patch
+++ /dev/null
@@ -1,95 +0,0 @@
---- a/ath_hal/ah_os.c
-+++ b/ath_hal/ah_os.c
-@@ -343,6 +343,46 @@ EXPORT_SYMBOL(ath_hal_func);
-  * NB: see the comments in ah_osdep.h about byte-swapping register
-  *     reads and writes to understand what's going on below.
-  */
-+
-+#ifdef CONFIG_LANTIQ
-+extern int lantiq_emulate_madwifi_eep;
-+extern unsigned long long lantiq_madwifi_eep_addr;
-+#define EEPROM_EMULATION 1
-+#endif
-+
-+#ifdef EEPROM_EMULATION
-+static int ath_hal_eeprom(struct ath_hal *ah, unsigned long addr, int val, int write)
-+{
-+	static int addrsel = 0;
-+	static int rc = 0;
-+
-+	if (write) {
-+		if(addr == 0x6000) {
-+			addrsel = val * 2;
-+			rc = 0;
-+		}
-+	} else {
-+		switch(addr)
-+		{
-+		case 0x600c:
-+			if(rc++ < 2)
-+				val = 0x00000000;
-+			else
-+				val = 0x00000002;
-+			break;
-+		case 0x6004:
-+			val = cpu_to_le16(__raw_readw((u16 *) KSEG1ADDR(lantiq_madwifi_eep_addr + addrsel)));
-+			/* this forces the regdomain to 0x00 (worldwide), as the original setting
-+			 * causes issues with the HAL */
-+			if (addrsel == 0x17e)
-+				val = 0;
-+			break;
-+		}
-+	}
-+	return val;
-+}
-+#endif
-+
- void __ahdecl
- ath_hal_reg_write(struct ath_hal *ah, u_int reg, u_int32_t val)
- {
-@@ -351,20 +391,33 @@ ath_hal_reg_write(struct ath_hal *ah, u_
- 		ath_hal_printf(ah, "%s: WRITE 0x%x <= 0x%x\n", 
- 				(ath_hal_func ?: "unknown"), reg, val);
- #endif
--	_OS_REG_WRITE(ah, reg, val);
-+#ifdef EEPROM_EMULATION
-+	if((reg >= 0x6000) && (reg <= 0x6010) && lantiq_emulate_madwifi_eep)
-+	{
-+		val = ath_hal_eeprom(ah, reg, val, 1);
-+	} else
-+#endif
-+		_OS_REG_WRITE(ah, reg, val);
- }
- EXPORT_SYMBOL(ath_hal_reg_write);
- 
-+
- /* This should only be called while holding the lock, sc->sc_hal_lock. */
- u_int32_t __ahdecl
- ath_hal_reg_read(struct ath_hal *ah, u_int reg)
- {
-- 	u_int32_t val;
-+	u_int32_t val;
-+#ifdef EEPROM_EMULATION
-+	if((reg >= 0x6000) && (reg <= 0x6010) && lantiq_emulate_madwifi_eep)
-+	{
-+		val = ath_hal_eeprom(ah, reg, 0, 0);
-+	} else
-+#endif
-+		val = _OS_REG_READ(ah, reg);
- 
--	val = _OS_REG_READ(ah, reg);
- #ifdef AH_DEBUG
- 	if (ath_hal_debug > 1)
--		ath_hal_printf(ah, "%s: READ 0x%x => 0x%x\n", 
-+		ath_hal_printf(ah, "%s: READ 0x%x => 0x%x\n",
- 				(ath_hal_func ?: "unknown"), reg, val);
- #endif
- 	return val;
-@@ -581,7 +634,6 @@ init_ath_hal(void)
- {
- 	const char *sep;
- 	int i;
--
- 	printk(KERN_INFO "%s: %s (", dev_info, ath_hal_version);
- 	sep = "";
- 	for (i = 0; ath_hal_buildopts[i] != NULL; i++) {
diff --git a/package/madwifi/patches/355-eap_auth_disassoc.patch b/package/madwifi/patches/355-eap_auth_disassoc.patch
deleted file mode 100644
index 8bb1e93236..0000000000
--- a/package/madwifi/patches/355-eap_auth_disassoc.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-This patch causes STA mode interfaces to disassociate if transmission of assoc/auth
-critical packets failed.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -8334,6 +8334,14 @@ ath_tx_processq(struct ath_softc *sc, st
- #endif
- 				if (ts->ts_status & HAL_TXERR_XRETRY) {
- 					sc->sc_stats.ast_tx_xretries++;
-+					if (SKB_CB(bf->bf_skb)->auth_pkt &&
-+						(ni->ni_vap->iv_opmode == IEEE80211_M_STA)) {
-+						struct ieee80211vap *vap = ni->ni_vap;
-+
-+						/* if roaming is enabled, try reassociating, otherwise
-+						 * disassociate and go back to the scan state */
-+						vap->iv_mgtsend.function(vap->iv_mgtsend.data);
-+					}
- 					if (ni->ni_flags & IEEE80211_NODE_UAPSD_TRIG) {
- 						ni->ni_stats.ns_tx_eosplost++;
- 						DPRINTF(sc, ATH_DEBUG_UAPSD,
---- a/net80211/ieee80211_linux.c
-+++ b/net80211/ieee80211_linux.c
-@@ -156,6 +156,7 @@ ieee80211_getmgtframe(u_int8_t **frm, u_
- 		if (off != 0)
- 			skb_reserve(skb, align - off);
- 
-+		SKB_CB(skb)->auth_pkt = 0;
- 		SKB_CB(skb)->ni = NULL;
- 		SKB_CB(skb)->flags = 0;
- 		SKB_CB(skb)->next = NULL;
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -393,6 +393,7 @@ typedef spinlock_t acl_lock_t;
- 	void		(*next_destructor)(struct sk_buff *skb);
- #endif
- 	struct sk_buff *next;			/* fast frame sk_buf chain */
-+	u_int8_t auth_pkt;
- };
- 
- 
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -778,6 +778,8 @@ ieee80211_encap(struct ieee80211_node *n
- 	else
- 		hdrsize = sizeof(struct ieee80211_frame);
- 
-+	SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE));
-+
- 	switch (vap->iv_opmode) {
- 	case IEEE80211_M_IBSS:
- 	case IEEE80211_M_AHDEMO:
-@@ -1622,6 +1624,7 @@ ieee80211_add_xr_param(u_int8_t *frm, st
- 	ie->param_len = frm - &ie->param_oui[0];
- 	return frm;
- }
-+
- #endif
- /*
-  * Send a probe request frame with the specified ssid
-@@ -1886,6 +1889,7 @@ ieee80211_send_mgmt(struct ieee80211_nod
- 				sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0));
- 		if (skb == NULL)
- 			senderr(ENOMEM, is_tx_nobuf);
-+		SKB_CB(skb)->auth_pkt = 1;
- 
- 		((__le16 *)frm)[0] =
- 			(is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED)
-@@ -1960,6 +1964,7 @@ ieee80211_send_mgmt(struct ieee80211_nod
- 			vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length);
- 		if (skb == NULL)
- 			senderr(ENOMEM, is_tx_nobuf);
-+		SKB_CB(skb)->auth_pkt = 1;
- 
- 		capinfo = 0;
- 		if (vap->iv_opmode == IEEE80211_M_IBSS)
diff --git a/package/madwifi/patches/356-hidden_ssid.patch b/package/madwifi/patches/356-hidden_ssid.patch
deleted file mode 100644
index b87569e762..0000000000
--- a/package/madwifi/patches/356-hidden_ssid.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-This patch fixes the detection of hidden SSIDs as transmitted
-by some cisco systems.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
---- a/net80211/ieee80211_scan_sta.c
-+++ b/net80211/ieee80211_scan_sta.c
-@@ -209,6 +209,19 @@ saveie(u_int8_t **iep, const u_int8_t *i
- 		ieee80211_saveie(iep, ie);
- }
- 
-+
-+static inline int is_empty_ssid(u_int8_t *ssid)
-+{
-+	if (!ssid)
-+		return 1;
-+	if (ssid[1] == 0)
-+		return 1;
-+	if ((ssid[1] == 1) && (ssid[2] == 0))
-+		return 1;
-+	return 0;
-+}
-+
-+
- /*
-  * Process a beacon or probe response frame; create an
-  * entry in the scan cache or update any previous entry.
-@@ -233,8 +246,8 @@ sta_add(struct ieee80211_scan_state *ss,
- 	SCAN_STA_LOCK_IRQ(st);
- 	LIST_FOREACH(se, &st->st_hash[hash], se_hash)
- 		if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) &&
--		    sp->ssid[1] == se->base.se_ssid[1] &&
--		    !memcmp(se->base.se_ssid+2, sp->ssid+2, se->base.se_ssid[1]))
-+		    (is_empty_ssid(sp->ssid) || (sp->ssid[1] == se->base.se_ssid[1] &&
-+		    !memcmp(se->base.se_ssid+2, sp->ssid+2, se->base.se_ssid[1]))))
- 			goto found;
- 
- 	MALLOC(se, struct sta_entry *, sizeof(struct sta_entry),
-@@ -252,8 +265,8 @@ found:
- 	ise = &se->base;
- 
- 	/* XXX ap beaconing multiple ssid w/ same bssid */
--	if (sp->ssid[1] != 0 &&
--	    (ISPROBE(subtype) || ise->se_ssid[1] == 0))
-+	if (!is_empty_ssid(sp->ssid) &&
-+	    (ISPROBE(subtype) || is_empty_ssid(ise->se_ssid)))
- 		memcpy(ise->se_ssid, sp->ssid, 2 + sp->ssid[1]);
- 
- 	memcpy(ise->se_rates, sp->rates, 
diff --git a/package/madwifi/patches/357-bgscan_thresh.patch b/package/madwifi/patches/357-bgscan_thresh.patch
deleted file mode 100644
index bf3483776f..0000000000
--- a/package/madwifi/patches/357-bgscan_thresh.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-Add an optional background scanning threshold triggered by low rssi
-(useful for passing updated scan results to the supplicant ahead of
-time, before losing connectivity entirely)
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -646,6 +646,7 @@ enum {
- 	IEEE80211_PARAM_MINRATE			= 76,	/* Minimum rate (by table index) */
- 	IEEE80211_PARAM_PROTMODE_RSSI		= 77,	/* RSSI Threshold for enabling protection mode */
- 	IEEE80211_PARAM_PROTMODE_TIMEOUT	= 78,	/* Timeout for expiring protection mode */
-+	IEEE80211_PARAM_BGSCAN_THRESH		= 79,	/* bg scan rssi threshold */
- };
- 
- #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -92,6 +92,8 @@
- #define	IEEE80211_BGSCAN_IDLE_MIN	100	/* min idle time (ms) */
- #define	IEEE80211_BGSCAN_IDLE_DEFAULT	250	/* default idle time (ms) */
- 
-+#define IEEE80211_BGSCAN_TRIGGER_INTVL 20 /* min trigger interval for thresh based bgscan (secs) */
-+
- #define IEEE80211_COVERAGE_CLASS_MAX	31	/* max coverage class */
- #define IEEE80211_REGCLASSIDS_MAX	10	/* max regclass id list */
- 
-@@ -219,6 +221,10 @@ struct ieee80211vap {
- 	u_int8_t iv_nickname[IEEE80211_NWID_LEN];
- 	u_int iv_bgscanidle;				/* bg scan idle threshold */
- 	u_int iv_bgscanintvl;				/* bg scan min interval */
-+	u_int iv_bgscanthr;					/* bg scan rssi threshold */
-+	u_int iv_bgscantrintvl;				/* bg scan trigger interval */
-+	unsigned long iv_bgscanthr_next;		/* last trigger for bgscan */
-+	unsigned long iv_lastconnect;	/* time of last connect attempt */
- 	u_int iv_scanvalid;				/* scan cache valid threshold */
- 	struct ieee80211_roam iv_roam;			/* sta-mode roaming state */
- 
-@@ -608,6 +614,7 @@ MALLOC_DECLARE(M_80211_VAP);
- #define IEEE80211_FEXT_SWBMISS		0x00000400	/* CONF: use software beacon timer */
- #define IEEE80211_FEXT_DROPUNENC_EAPOL	0x00000800	/* CONF: drop unencrypted eapol frames */
- #define IEEE80211_FEXT_APPIE_UPDATE	0x00001000	/* STATE: beacon APP IE updated */
-+#define IEEE80211_FEXT_BGSCAN_THR	0x00002000	/* bgscan due to low rssi */
- 
- #define IEEE80211_COM_UAPSD_ENABLE(_ic)		((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD)
- #define IEEE80211_COM_UAPSD_DISABLE(_ic)	((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD)
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2744,6 +2744,9 @@ ieee80211_ioctl_setparam(struct net_devi
- 		else
- 			retv = EINVAL;
- 		break;
-+	case IEEE80211_PARAM_BGSCAN_THRESH:
-+		vap->iv_bgscanthr = value;
-+		break;
- 	case IEEE80211_PARAM_MCAST_RATE:
- 		/* units are in KILObits per second */
- 		if (value >= 256 && value <= 54000)
-@@ -3144,6 +3147,9 @@ ieee80211_ioctl_getparam(struct net_devi
- 	case IEEE80211_PARAM_BGSCAN_INTERVAL:
- 		param[0] = vap->iv_bgscanintvl / HZ;	/* seconds */
- 		break;
-+	case IEEE80211_PARAM_BGSCAN_THRESH:
-+		param[0] = vap->iv_bgscanthr;	/* rssi */
-+		break;
- 	case IEEE80211_PARAM_MCAST_RATE:
- 		param[0] = vap->iv_mcast_rate;	/* seconds */
- 		break;
-@@ -5666,6 +5672,10 @@ static const struct iw_priv_args ieee802
- 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanintvl" },
- 	{ IEEE80211_PARAM_BGSCAN_INTERVAL,
- 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanintvl" },
-+	{ IEEE80211_PARAM_BGSCAN_THRESH,
-+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanthr" },
-+	{ IEEE80211_PARAM_BGSCAN_THRESH,
-+	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanthr" },
- 	{ IEEE80211_PARAM_MCAST_RATE,
- 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcast_rate" },
- 	{ IEEE80211_PARAM_MCAST_RATE,
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -3013,8 +3013,10 @@ contbgscan(struct ieee80211vap *vap)
- {
- 	struct ieee80211com *ic = vap->iv_ic;
- 
-+	vap->iv_bgscantrintvl = (vap->iv_bgscantrintvl + 1) % 4;
- 	return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) &&
--		time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle));
-+		(((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && !vap->iv_bgscantrintvl) ||
-+			time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle)));
- }
- 
- static __inline int
-@@ -3258,6 +3260,25 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			/* record tsf of last beacon */
- 			memcpy(ni->ni_tstamp.data, scan.tstamp,
- 				sizeof(ni->ni_tstamp));
-+
-+			/* When rssi is low, start doing bgscans more frequently to allow
-+			 * the supplicant to make a better switching decision */
-+			if (!(ic->ic_flags & IEEE80211_F_SCAN) && (rssi < vap->iv_bgscanthr) &&
-+					(!vap->iv_bgscanthr_next ||
-+						!time_before(jiffies, vap->iv_bgscanthr_next)) &&
-+					(vap->iv_state == IEEE80211_S_RUN) &&
-+					time_after(jiffies, vap->iv_lastconnect +
-+						msecs_to_jiffies(IEEE80211_BGSCAN_INTVAL_MIN * 1000))) {
-+				int ret;
-+
-+				ic->ic_lastdata = 0;
-+				ic->ic_lastscan = 0;
-+				ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN_THR;
-+				ret = ieee80211_bg_scan(vap);
-+				if (ret)
-+					vap->iv_bgscanthr_next = jiffies + msecs_to_jiffies(IEEE80211_BGSCAN_TRIGGER_INTVL * 1000);
-+			}
-+
- 			if (ni->ni_intval != scan.bintval) {
- 				IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
- 						"beacon interval divergence: "
---- a/net80211/ieee80211_scan.c
-+++ b/net80211/ieee80211_scan.c
-@@ -616,6 +616,7 @@ ieee80211_cancel_scan(struct ieee80211va
- 
- 		/* clear bg scan NOPICK and mark cancel request */
- 		ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
-+		ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN_THR;
- 		SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL;
- 		ss->ss_ops->scan_cancel(ss, vap);
- 		/* force it to fire asap */
-@@ -782,7 +783,7 @@ again:
- 				ieee80211_sta_pwrsave(vap, 0);
- 				if (ss->ss_next >= ss->ss_last) {
- 					ieee80211_notify_scan_done(vap);
--					ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;
-+					ic->ic_flags_ext &= ~(IEEE80211_FEXT_BGSCAN|IEEE80211_FEXT_BGSCAN_THR);
- 				}
- 			}
- 			SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_CANCEL;
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -1450,6 +1450,7 @@ __ieee80211_newstate(struct ieee80211vap
- 		}
- 		break;
- 	case IEEE80211_S_AUTH:
-+		vap->iv_lastconnect = jiffies;
- 		/* auth frames are possible between IBSS nodes, 
- 		 * see 802.11-1999, chapter 5.7.6 */
- 		KASSERT(vap->iv_opmode == IEEE80211_M_STA || 
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -238,7 +238,8 @@ ieee80211_hardstart(struct sk_buff *skb,
- 	}
- 	
- 	/* Cancel any running BG scan */
--	ieee80211_cancel_scan(vap);
-+	if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && (vap->iv_state == IEEE80211_S_RUN))
-+		ieee80211_cancel_scan(vap);
- 
- 	/* 
- 	 * Find the node for the destination so we can do
diff --git a/package/madwifi/patches/358-ignore_broken_bssid.patch b/package/madwifi/patches/358-ignore_broken_bssid.patch
deleted file mode 100644
index b549272202..0000000000
--- a/package/madwifi/patches/358-ignore_broken_bssid.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-Some misconfigured APs broadcast NULL BSSIDs, which can confuse the STA
-Ignore those when scanning.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
---- a/net80211/ieee80211_scan_sta.c
-+++ b/net80211/ieee80211_scan_sta.c
-@@ -242,6 +242,10 @@ sta_add(struct ieee80211_scan_state *ss,
- 	struct ieee80211_scan_entry *ise;
- 	int hash;
- 
-+	/* workaround for broken APs that broadcast NULL BSSIDs */
-+	if (memcmp(wh->i_addr3, "\x00\x00\x00\x00\x00\x00", 6) == 0)
-+		return 0;
-+
- 	hash = STA_HASH(macaddr);
- 	SCAN_STA_LOCK_IRQ(st);
- 	LIST_FOREACH(se, &st->st_hash[hash], se_hash)
diff --git a/package/madwifi/patches/359-disable_reassoc.patch b/package/madwifi/patches/359-disable_reassoc.patch
deleted file mode 100644
index 8d25dc2a8e..0000000000
--- a/package/madwifi/patches/359-disable_reassoc.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-Add a preliminary fix for the reassoc check, but disable reassoc entirely for now
-until we've figured out why it fails frequently.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -599,10 +599,9 @@ ieee80211_ibss_merge(struct ieee80211_no
- EXPORT_SYMBOL(ieee80211_ibss_merge);
- 
- static __inline int
--ssid_equal(const struct ieee80211_node *a, const struct ieee80211_node *b)
-+bssid_equal(const struct ieee80211_node *a, const struct ieee80211_node *b)
- {
--	return (a->ni_esslen == b->ni_esslen &&
--		memcmp(a->ni_essid, b->ni_essid, a->ni_esslen) == 0);
-+	return (memcmp(a->ni_bssid, b->ni_bssid, IEEE80211_ADDR_LEN) == 0);
- }
- 
- /*
-@@ -634,8 +633,8 @@ ieee80211_sta_join1(struct ieee80211_nod
- 	 * Check if old+new node have the same ssid in which
- 	 * case we can reassociate when operating in sta mode.
- 	 */
--	canreassoc = ((obss != NULL) &&
--		(vap->iv_state == IEEE80211_S_RUN) && ssid_equal(obss, selbs));
-+	canreassoc = 0; /* ((obss != NULL) &&
-+		(vap->iv_state == IEEE80211_S_RUN) && bssid_equal(obss, selbs)); */
- 	vap->iv_bss = selbs;
- 	IEEE80211_ADDR_COPY(vap->iv_bssid, selbs->ni_bssid);
- 	if (obss != NULL)
diff --git a/package/madwifi/patches/360-sta_nodes.patch b/package/madwifi/patches/360-sta_nodes.patch
deleted file mode 100644
index 8d2dd9ddd6..0000000000
--- a/package/madwifi/patches/360-sta_nodes.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-Drop stale AP nodes from the client list when disconnecting.
-Fixes some reassoc issues.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -1348,7 +1348,7 @@ __ieee80211_newstate(struct ieee80211vap
- 				IEEE80211_SEND_MGMT(ni,
- 					IEEE80211_FC0_SUBTYPE_DISASSOC,
- 					IEEE80211_REASON_ASSOC_LEAVE);
--				ieee80211_sta_leave(ni);
-+				ieee80211_node_leave(ni);
- 				break;
- 			case IEEE80211_M_HOSTAP:
- 				ieee80211_iterate_nodes(&ic->ic_sta,
-@@ -1358,12 +1358,14 @@ __ieee80211_newstate(struct ieee80211vap
- 				break;
- 			}
- 			goto reset;
-+		case IEEE80211_S_AUTH:
- 		case IEEE80211_S_ASSOC:
- 			switch (vap->iv_opmode) {
- 			case IEEE80211_M_STA:
- 				IEEE80211_SEND_MGMT(ni,
- 					IEEE80211_FC0_SUBTYPE_DEAUTH,
- 					IEEE80211_REASON_AUTH_LEAVE);
-+				ieee80211_node_leave(ni);
- 				break;
- 			case IEEE80211_M_HOSTAP:
- 				ieee80211_iterate_nodes(&ic->ic_sta,
-@@ -1376,7 +1378,6 @@ __ieee80211_newstate(struct ieee80211vap
- 		case IEEE80211_S_SCAN:
- 			ieee80211_cancel_scan(vap);
- 			goto reset;
--		case IEEE80211_S_AUTH:
- 		reset:
- 			ieee80211_reset_bss(vap);
- 			break;
-@@ -1429,10 +1430,12 @@ __ieee80211_newstate(struct ieee80211vap
- 					IEEE80211_SCAN_FOREVER,
- 					vap->iv_des_nssid, vap->iv_des_ssid,
- 					NULL);
-+			else
-+				ieee80211_node_leave(vap->iv_bss);
- 			break;
- 		case IEEE80211_S_RUN:		/* beacon miss */
- 			if (vap->iv_opmode == IEEE80211_M_STA) {
--				ieee80211_sta_leave(ni);
-+				ieee80211_node_leave(ni);
- 				vap->iv_flags &= ~IEEE80211_F_SIBSS;	/* XXX */
- 				if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
- 					ieee80211_check_scan(vap,
-@@ -1511,7 +1514,7 @@ __ieee80211_newstate(struct ieee80211vap
- 				IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
- 			break;
- 		case IEEE80211_S_RUN:
--			ieee80211_sta_leave(ni);
-+			ieee80211_node_leave(ni);
- 			if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
- 				/* NB: caller specifies ASSOC/REASSOC by arg */
- 				IEEE80211_SEND_MGMT(ni, arg ?
-@@ -1779,6 +1782,7 @@ ieee80211_newstate(struct ieee80211vap *
- 			  ieee80211_state_name[nstate], 
- 			  ieee80211_state_name[dstate]);
- 
-+	ieee80211_update_link_status(vap, nstate, ostate);
- 	switch (nstate) {
- 	case IEEE80211_S_AUTH:
- 	case IEEE80211_S_ASSOC:
---- a/net80211/ieee80211_linux.c
-+++ b/net80211/ieee80211_linux.c
-@@ -233,33 +233,59 @@ ieee80211_vlan_vdetach(struct ieee80211v
- }
- 
- void
--ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
-+ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate)
- {
--	struct ieee80211vap *vap = ni->ni_vap;
- 	struct net_device *dev = vap->iv_dev;
- 	union iwreq_data wreq;
-+	int active;
-+
-+	if (vap->iv_opmode != IEEE80211_M_STA)
-+		return;
-+
-+	if (ostate == nstate)
-+		return;
-+
-+	if (nstate == IEEE80211_S_RUN)
-+		active = 1;
-+	else if ((ostate >= IEEE80211_S_AUTH) && (nstate < ostate))
-+		active = 0;
-+	else
-+		return;
-+
-+	if (active && !vap->iv_bss)
-+		return;
-+
-+	memset(&wreq, 0, sizeof(wreq));
-+	wreq.ap_addr.sa_family = ARPHRD_ETHER;
- 
--	if (ni == vap->iv_bss) {
--		if (newassoc)
--			netif_carrier_on(dev);
--		memset(&wreq, 0, sizeof(wreq));
-+	if (active) {
-+		//netif_carrier_on(vap->iv_dev);
- 		IEEE80211_ADDR_COPY(wreq.addr.sa_data, vap->iv_bssid);
--		wreq.addr.sa_family = ARPHRD_ETHER;
--#ifdef ATH_SUPERG_XR
--		if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
--			dev = vap->iv_xrvap->iv_dev;
--#endif
--		wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
- 	} else {
--		memset(&wreq, 0, sizeof(wreq));
--		IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
--		wreq.addr.sa_family = ARPHRD_ETHER;
-+		//netif_carrier_off(vap->iv_dev);
-+		memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
-+	}
-+	wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
-+}
-+
-+void
-+ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
-+{
-+	struct ieee80211vap *vap = ni->ni_vap;
-+	struct net_device *dev = vap->iv_dev;
-+	union iwreq_data wreq;
-+
-+	if (ni == vap->iv_bss)
-+		return;
-+
-+	memset(&wreq, 0, sizeof(wreq));
-+	IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
-+	wreq.addr.sa_family = ARPHRD_ETHER;
- #ifdef ATH_SUPERG_XR
--		if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
--			dev = vap->iv_xrvap->iv_dev;
-+	if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
-+		dev = vap->iv_xrvap->iv_dev;
- #endif
--		wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
--	}
-+	wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
- }
- 
- void
-@@ -269,18 +295,14 @@ ieee80211_notify_node_leave(struct ieee8
- 	struct net_device *dev = vap->iv_dev;
- 	union iwreq_data wreq;
- 
--	if (ni == vap->iv_bss) {
--		netif_carrier_off(dev);
--		memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
--		wreq.ap_addr.sa_family = ARPHRD_ETHER;
--		wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
--	} else {
--		/* fire off wireless event station leaving */
--		memset(&wreq, 0, sizeof(wreq));
--		IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
--		wreq.addr.sa_family = ARPHRD_ETHER;
--		wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL);
--	}
-+	if (ni == vap->iv_bss)
-+		return;
-+
-+	/* fire off wireless event station leaving */
-+	memset(&wreq, 0, sizeof(wreq));
-+	IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
-+	wreq.addr.sa_family = ARPHRD_ETHER;
-+	wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL);
- }
- 
- void
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -2332,6 +2332,7 @@ ieee80211_node_leave(struct ieee80211_no
- 		count_suppchans(ic, ni, -1);
- 	IEEE80211_UNLOCK_IRQ(ic);
- 
-+done:
- 	/*
- 	 * Cleanup station state.  In particular clear various
- 	 * state that might otherwise be reused if the node
-@@ -2339,7 +2340,7 @@ ieee80211_node_leave(struct ieee80211_no
- 	 * (and memory is reclaimed).
- 	 */
- 	ieee80211_sta_leave(ni);
--done:
-+
- 	/* Run a cleanup */
- #ifdef IEEE80211_DEBUG_REFCNT
- 	ic->ic_node_cleanup_debug(ni, __func__, __LINE__);
---- a/net80211/ieee80211_node.h
-+++ b/net80211/ieee80211_node.h
-@@ -60,7 +60,7 @@
- #define	IEEE80211_INACT_PROBE	(30/IEEE80211_INACT_WAIT)	/* probe */
- #define	IEEE80211_INACT_SCAN	(300/IEEE80211_INACT_WAIT)	/* scanned */
- 
--#define	IEEE80211_TRANS_WAIT 	5				/* mgt frame tx timer (secs) */
-+#define	IEEE80211_TRANS_WAIT	300				/* mgt frame tx timer (msecs) */
- 
- #define	IEEE80211_NODE_HASHSIZE	32
- /* simple hash is enough for variation of macaddr */
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -2141,7 +2141,7 @@ ieee80211_send_mgmt(struct ieee80211_nod
- 
- 	ieee80211_mgmt_output(ieee80211_ref_node(ni), skb, type);
- 	if (timer)
--		mod_timer(&vap->iv_mgtsend, jiffies + timer * HZ);
-+		mod_timer(&vap->iv_mgtsend, jiffies + msecs_to_jiffies(timer));
- 	return 0;
- bad:
- 	return ret;
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -514,8 +514,9 @@ ieee80211_ioctl_siwap(struct net_device
- 			vap->iv_flags |= IEEE80211_F_DESBSSID;
- 
- 		IEEE80211_ADDR_COPY(vap->iv_des_bssid, &ap_addr->sa_data);
--		if (IS_UP_AUTO(vap))
-+		if (IS_UP(vap->iv_dev)) {
- 			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
-+		}
- 	}
- 	return 0;
- }
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -643,6 +643,7 @@ void ieee80211_vlan_vdetach(struct ieee8
- #define	free_netdev(dev)	kfree(dev)
- #endif
- 
-+void ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate);
- void ieee80211_ioctl_vattach(struct ieee80211vap *);
- void ieee80211_ioctl_vdetach(struct ieee80211vap *);
- struct ifreq;
diff --git a/package/madwifi/patches/361-bmiss_handling.patch b/package/madwifi/patches/361-bmiss_handling.patch
deleted file mode 100644
index 15d238f7b4..0000000000
--- a/package/madwifi/patches/361-bmiss_handling.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-Improve the beacon miss handling. Instead of just dropping the connection,
-send a directed probe request to the AP to see if it's still responding.
-Schedule a software beacon miss timer in this case, which adds a timeout
-for the APs probe response.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -3400,12 +3400,17 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			}
- 
- 			/* WDS/Repeater: re-schedule software beacon timer for 
--			 * STA. */
--			if ((vap->iv_state == IEEE80211_S_RUN) &&
--			    (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) {
--				mod_timer(&vap->iv_swbmiss, 
-+			 * STA. Reset consecutive bmiss counter as well */
-+			IEEE80211_LOCK_IRQ(ic);
-+			if (vap->iv_state == IEEE80211_S_RUN) {
-+				vap->iv_bmiss_count = 0;
-+				if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)
-+					mod_timer(&vap->iv_swbmiss,
- 						jiffies + vap->iv_swbmiss_period);
-+				else
-+					del_timer(&vap->iv_swbmiss);
- 			}
-+			IEEE80211_UNLOCK_IRQ(ic);
- 
- 			/* If scanning, pass the info to the scan module.
- 			 * Otherwise, check if it's the right time to do
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -1209,6 +1209,8 @@ ieee80211_beacon_miss(struct ieee80211co
- 	}
- 	/* XXX locking */
- 	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+		int count;
-+
- 		IEEE80211_DPRINTF(vap,
- 			IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
- 			"%s\n", "beacon miss");
-@@ -1221,6 +1223,29 @@ ieee80211_beacon_miss(struct ieee80211co
- 		if (vap->iv_opmode != IEEE80211_M_STA ||
- 		    vap->iv_state != IEEE80211_S_RUN)
- 			continue;
-+
-+		IEEE80211_LOCK_IRQ(ic);
-+		count = vap->iv_bmiss_count++;
-+		if (count) {
-+			/* if the counter was already above zero, reset it
-+			 * here, since we're going to do the bmiss handling
-+			 * in any case */
-+			vap->iv_bmiss_count = 0;
-+		} else {
-+			/* schedule the software beacon miss timer, it will be
-+			 * cancelled, if the probe request is acked */
-+			mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period);
-+		}
-+		IEEE80211_UNLOCK_IRQ(ic);
-+
-+		if (!count) {
-+			ieee80211_send_probereq(vap->iv_bss, vap->iv_myaddr,
-+				vap->iv_bss->ni_bssid, vap->iv_bss->ni_bssid,
-+				vap->iv_bss->ni_essid, vap->iv_bss->ni_esslen,
-+				NULL, 0);
-+			continue;
-+		}
-+
- 		if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
- #ifdef ATH_SUPERG_DYNTURBO
- 			/* 
-@@ -1621,14 +1646,14 @@ __ieee80211_newstate(struct ieee80211vap
- 		}
- 
- 		/* WDS/Repeater: Start software beacon timer for STA */
-+		vap->iv_swbmiss.function = ieee80211_sta_swbmiss;
-+		vap->iv_swbmiss.data = (unsigned long) vap;
-+		vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES(
-+			vap->iv_ic->ic_bmissthreshold * ni->ni_intval);
-+
- 		if (ostate != IEEE80211_S_RUN &&
- 		    (vap->iv_opmode == IEEE80211_M_STA &&
- 		     vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) {
--			vap->iv_swbmiss.function = ieee80211_sta_swbmiss;
--			vap->iv_swbmiss.data = (unsigned long) vap;
--			vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES(
--				vap->iv_ic->ic_bmissthreshold * ni->ni_intval);
--
- 			mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period);
- 		}
- 
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -283,6 +283,7 @@ struct ieee80211vap {
- 
- 	struct timer_list iv_swbmiss;			/* software beacon miss timer */
- 	u_int16_t iv_swbmiss_period; 			/* software beacon miss timer period */
-+	u_int16_t iv_bmiss_count;			/* consecutive beacon miss counter */
- 	struct ieee80211_nsparams iv_nsparams;		/* new state parameters for tasklet for stajoin1 */
- 	struct IEEE80211_TQ_STRUCT iv_stajoin1tq; 	/* tasklet for newstate action called from stajoin1tq */
- 	unsigned int iv_nsdone;				/* Done with scheduled newstate tasklet */
diff --git a/package/madwifi/patches/362-rssithr.patch b/package/madwifi/patches/362-rssithr.patch
deleted file mode 100644
index 5a86833bb5..0000000000
--- a/package/madwifi/patches/362-rssithr.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-Add an optional threshold for low-rssi disconnection. This can be useful
-when letting wpa_supplicant control roaming.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -647,6 +647,8 @@ enum {
- 	IEEE80211_PARAM_PROTMODE_RSSI		= 77,	/* RSSI Threshold for enabling protection mode */
- 	IEEE80211_PARAM_PROTMODE_TIMEOUT	= 78,	/* Timeout for expiring protection mode */
- 	IEEE80211_PARAM_BGSCAN_THRESH		= 79,	/* bg scan rssi threshold */
-+	IEEE80211_PARAM_RSSI_DIS_THR	= 80,	/* rssi threshold for disconnection */
-+	IEEE80211_PARAM_RSSI_DIS_COUNT	= 81,	/* counter for rssi threshold */
- };
- 
- #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2799,6 +2799,12 @@ ieee80211_ioctl_setparam(struct net_devi
- 	case IEEE80211_PARAM_ROAM_RATE_11G:
- 		vap->iv_roam.rate11b = value;
- 		break;
-+	case IEEE80211_PARAM_RSSI_DIS_THR:
-+		vap->iv_rssi_dis_thr = value;
-+		break;
-+	case IEEE80211_PARAM_RSSI_DIS_COUNT:
-+		vap->iv_rssi_dis_max = value;
-+		break;
- 	case IEEE80211_PARAM_UAPSDINFO:
- 		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
- 			if (ic->ic_caps & IEEE80211_C_UAPSD) {
-@@ -3184,6 +3190,12 @@ ieee80211_ioctl_getparam(struct net_devi
- 	case IEEE80211_PARAM_ROAM_RATE_11G:
- 		param[0] = vap->iv_roam.rate11b;
- 		break;
-+	case IEEE80211_PARAM_RSSI_DIS_THR:
-+		param[0] = vap->iv_rssi_dis_thr;
-+		break;
-+	case IEEE80211_PARAM_RSSI_DIS_COUNT:
-+		param[0] = vap->iv_rssi_dis_max;
-+		break;
- 	case IEEE80211_PARAM_UAPSDINFO:
- 		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
- 			if (IEEE80211_VAP_UAPSD_ENABLED(vap))
-@@ -5733,6 +5745,14 @@ static const struct iw_priv_args ieee802
- 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rate11g" },
- 	{ IEEE80211_PARAM_ROAM_RATE_11G,
- 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rate11g" },
-+	{ IEEE80211_PARAM_RSSI_DIS_THR,
-+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_disthr" },
-+	{ IEEE80211_PARAM_RSSI_DIS_THR,
-+	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_disthr" },
-+	{ IEEE80211_PARAM_RSSI_DIS_COUNT,
-+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_discnt" },
-+	{ IEEE80211_PARAM_RSSI_DIS_COUNT,
-+	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_discnt" },
- 	{ IEEE80211_PARAM_UAPSDINFO,
- 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "uapsd" },
- 	{ IEEE80211_PARAM_UAPSDINFO,
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -3261,6 +3261,19 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			memcpy(ni->ni_tstamp.data, scan.tstamp,
- 				sizeof(ni->ni_tstamp));
- 
-+			/* when rssi falls below the disconnection threshold, drop the connection */
-+			if ((vap->iv_rssi_dis_thr > 0) && (vap->iv_rssi_dis_max > 0)) {
-+				if ((rssi > 0) && (rssi < vap->iv_rssi_dis_thr)) {
-+					if (++vap->iv_rssi_dis_trig > vap->iv_rssi_dis_max) {
-+						vap->iv_rssi_dis_trig = 0;
-+						ieee80211_node_leave(ni);
-+						return;
-+					}
-+				} else {
-+					vap->iv_rssi_dis_trig = 0;
-+				}
-+			}
-+
- 			/* When rssi is low, start doing bgscans more frequently to allow
- 			 * the supplicant to make a better switching decision */
- 			if (!(ic->ic_flags & IEEE80211_F_SCAN) && (rssi < vap->iv_bgscanthr) &&
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -223,6 +223,9 @@ struct ieee80211vap {
- 	u_int iv_bgscanintvl;				/* bg scan min interval */
- 	u_int iv_bgscanthr;					/* bg scan rssi threshold */
- 	u_int iv_bgscantrintvl;				/* bg scan trigger interval */
-+	u_int iv_rssi_dis_thr;				/* rssi disassoc threshold */
-+	u_int iv_rssi_dis_max;				/* max beacons below disconnect threshold */
-+	u_int iv_rssi_dis_trig;				/* rssi disassoc trigger count */
- 	unsigned long iv_bgscanthr_next;		/* last trigger for bgscan */
- 	unsigned long iv_lastconnect;	/* time of last connect attempt */
- 	u_int iv_scanvalid;				/* scan cache valid threshold */
diff --git a/package/madwifi/patches/363-fix_turbo.patch b/package/madwifi/patches/363-fix_turbo.patch
deleted file mode 100644
index 880f2d6144..0000000000
--- a/package/madwifi/patches/363-fix_turbo.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -4925,7 +4925,7 @@ ath_beacon_generate(struct ath_softc *sc
- 	 * capability info and arrange for a mode change
- 	 * if needed.
- 	 */
--	if (sc->sc_dturbo) {
-+	if (sc->sc_dturbo && NULL != avp->av_boff.bo_tim) {
- 		u_int8_t dtim;
- 		dtim = ((avp->av_boff.bo_tim[2] == 1) ||
- 			(avp->av_boff.bo_tim[3] == 1));
diff --git a/package/madwifi/patches/364-memory_alloc.patch b/package/madwifi/patches/364-memory_alloc.patch
deleted file mode 100644
index 53fbc77091..0000000000
--- a/package/madwifi/patches/364-memory_alloc.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -539,8 +539,8 @@ ath_attach(u_int16_t devid, struct net_d
- 
- 	/* Allocate space for dynamically determined maximum VAP count */
- 	sc->sc_bslot = 
--		kmalloc(ath_maxvaps * sizeof(struct ieee80211vap), GFP_KERNEL);
--	memset(sc->sc_bslot, 0, ath_maxvaps * sizeof(struct ieee80211vap));
-+		kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
-+	memset(sc->sc_bslot, 0, ath_maxvaps * sizeof(struct ieee80211vap*));
- 
- 	/*
- 	 * Cache line size is used to size and align various
diff --git a/package/madwifi/patches/365-turbo_channelsearch.patch b/package/madwifi/patches/365-turbo_channelsearch.patch
deleted file mode 100644
index df4306b212..0000000000
--- a/package/madwifi/patches/365-turbo_channelsearch.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -684,6 +684,7 @@ ieee80211_find_channel(struct ieee80211c
- 	int i;
- 
- 	/* Brute force search */
-+	flags &= IEEE80211_CHAN_ALLTURBO;
- 	for (i = 0; i < ic->ic_nchans; i++) {
- 		c = &ic->ic_channels[i];
- 		if (c->ic_freq == freq &&
diff --git a/package/madwifi/patches/366-bstuck_thresh.patch b/package/madwifi/patches/366-bstuck_thresh.patch
deleted file mode 100644
index cde1f5c98c..0000000000
--- a/package/madwifi/patches/366-bstuck_thresh.patch
+++ /dev/null
@@ -1,52 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -389,6 +389,7 @@ static int ath_countrycode = CTRY_DEFAUL
- static int ath_outdoor = AH_FALSE;		/* enable outdoor use */
- static int ath_xchanmode = AH_TRUE;		/* enable extended channels */
- static int ath_maxvaps = ATH_MAXVAPS_DEFAULT;   /* set default maximum vaps */
-+static int bstuck_thresh = BSTUCK_THRESH;       /* Stuck beacon count required for reset */
- static char *autocreate = NULL;
- static char *ratectl = DEF_RATE_CTL;
- static int rfkill = 0;
-@@ -432,6 +433,7 @@ MODULE_PARM(rfkill, "i");
- #ifdef ATH_CAP_TPC
- MODULE_PARM(tpc, "i");
- #endif
-+MODULE_PARM(bstuck_thresh, "i");
- MODULE_PARM(autocreate, "s");
- MODULE_PARM(ratectl, "s");
- #else
-@@ -445,6 +447,7 @@ module_param(rfkill, int, 0600);
- #ifdef ATH_CAP_TPC
- module_param(tpc, int, 0600);
- #endif
-+module_param(bstuck_thresh, int, 0600);
- module_param(autocreate, charp, 0600);
- module_param(ratectl, charp, 0600);
- #endif
-@@ -457,6 +460,7 @@ MODULE_PARM_DESC(rfkill, "Enable/disable
- MODULE_PARM_DESC(tpc, "Enable/disable per-packet transmit power control (TPC) "
- 		"capability");
- #endif
-+MODULE_PARM_DESC(bstuck_thresh, "Override default stuck beacon threshold");
- MODULE_PARM_DESC(autocreate, "Create ath device in "
- 		"[sta|ap|wds|adhoc|ahdemo|monitor] mode. defaults to sta, use "
- 		"'none' to disable");
-@@ -5072,7 +5076,7 @@ ath_beacon_send(struct ath_softc *sc, in
- 		DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
- 			"Missed %u consecutive beacons (n_beacon=%u)\n",
- 			sc->sc_bmisscount, n_beacon);
--		if (sc->sc_bmisscount > BSTUCK_THRESH)
-+		if (sc->sc_bmisscount > bstuck_thresh)
- 			ATH_SCHEDULE_TQUEUE(&sc->sc_bstucktq, needmark);
- 		return;
- 	}
-@@ -5230,7 +5234,7 @@ ath_bstuck_tasklet(TQUEUE_ARG data)
- 	 *     check will be true, in which case return
- 	 *     without resetting the driver.
- 	 */
--	if (sc->sc_bmisscount <= BSTUCK_THRESH)
-+	if (sc->sc_bmisscount <= bstuck_thresh)
- 		return;
- 	EPRINTF(sc, "Stuck beacon; resetting (beacon miss count: %u)\n",
- 		sc->sc_bmisscount);
diff --git a/package/madwifi/patches/367-roaming.patch b/package/madwifi/patches/367-roaming.patch
deleted file mode 100644
index 5950f9fd4e..0000000000
--- a/package/madwifi/patches/367-roaming.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-Patch adapted from ubnt madwifi patchset
-
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -659,7 +659,7 @@ ieee80211_sta_join1(struct ieee80211_nod
- 		 */
- 		if (canreassoc) {
- 			vap->iv_nsparams.newstate = IEEE80211_S_ASSOC;
--			vap->iv_nsparams.arg = 0;
-+			vap->iv_nsparams.arg = IEEE80211_FC0_SUBTYPE_REASSOC_REQ;
- 			IEEE80211_SCHEDULE_TQUEUE(&vap->iv_stajoin1tq);
- 		} else {
- 			vap->iv_nsparams.newstate = IEEE80211_S_AUTH;
---- a/net80211/ieee80211_scan_sta.c
-+++ b/net80211/ieee80211_scan_sta.c
-@@ -748,14 +748,17 @@ notfound:
-  * a reference to an entry w/o holding the lock on the table.
-  */
- static struct sta_entry *
--sta_lookup(struct sta_table *st, const u_int8_t macaddr[IEEE80211_ADDR_LEN])
-+sta_lookup(struct sta_table *st, const u_int8_t macaddr[IEEE80211_ADDR_LEN], struct ieee80211_scan_ssid* essid)
- {
- 	struct sta_entry *se;
- 	int hash = STA_HASH(macaddr);
- 
- 	SCAN_STA_LOCK_IRQ(st);
- 	LIST_FOREACH(se, &st->st_hash[hash], se_hash)
--		if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
-+		if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) &&
-+		    (essid->len == se->base.se_ssid[1] &&
-+		     !memcmp(se->base.se_ssid+2, essid->ssid,
-+			     se->base.se_ssid[1])))
- 			break;
- 	SCAN_STA_UNLOCK_IRQ(st);
- 
-@@ -772,7 +775,7 @@ sta_roam_check(struct ieee80211_scan_sta
- 	u_int8_t roamRate, curRate;
- 	int8_t roamRssi, curRssi;
- 
--	se = sta_lookup(st, ni->ni_macaddr);
-+	se = sta_lookup(st, ni->ni_macaddr, ss->ss_ssid);
- 	if (se == NULL) {
- 		/* XXX something is wrong */
- 		return;
-@@ -866,8 +869,8 @@ sta_age(struct ieee80211_scan_state *ss)
- 	 */
- 	KASSERT(vap->iv_opmode == IEEE80211_M_STA,
- 		("wrong mode %u", vap->iv_opmode));
--	/* XXX turn this off until the ap release is cut */
--	if (0 && vap->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO &&
-+	if (vap->iv_opmode == IEEE80211_M_STA &&
-+	    vap->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO &&
- 	    vap->iv_state >= IEEE80211_S_RUN)
- 		/* XXX vap is implicit */
- 		sta_roam_check(ss, vap);
-@@ -922,7 +925,11 @@ sta_assoc_fail(struct ieee80211_scan_sta
- 	struct sta_table *st = ss->ss_priv;
- 	struct sta_entry *se;
- 
--	se = sta_lookup(st, macaddr);
-+	/* Let outside apps to decide what peer is blacklisted */
-+	if (ss->ss_vap->iv_ic->ic_roaming == IEEE80211_ROAMING_MANUAL)
-+		return;
-+
-+	se = sta_lookup(st, macaddr, ss->ss_ssid);
- 	if (se != NULL) {
- 		se->se_fails++;
- 		se->se_lastfail = jiffies;
-@@ -939,7 +946,7 @@ sta_assoc_success(struct ieee80211_scan_
- 	struct sta_table *st = ss->ss_priv;
- 	struct sta_entry *se;
- 
--	se = sta_lookup(st, macaddr);
-+	se = sta_lookup(st, macaddr, ss->ss_ssid);
- 	if (se != NULL) {
- #if 0
- 		se->se_fails = 0;
diff --git a/package/madwifi/patches/368-sta_ie_preserve.patch b/package/madwifi/patches/368-sta_ie_preserve.patch
deleted file mode 100644
index fbd779ea0b..0000000000
--- a/package/madwifi/patches/368-sta_ie_preserve.patch
+++ /dev/null
@@ -1,49 +0,0 @@
---- a/net80211/ieee80211_scan_sta.c
-+++ b/net80211/ieee80211_scan_sta.c
-@@ -201,8 +201,10 @@ sta_flush_table(struct sta_table *st)
- }
- 
- static void
--saveie(u_int8_t **iep, const u_int8_t *ie)
-+saveie(u_int8_t **iep, const u_int8_t *ie, int preserve)
- {
-+	if (preserve && *iep)
-+		return;
- 	if (ie == NULL)
- 		*iep = NULL;
- 	else
-@@ -304,10 +306,10 @@ found:
- 		    (const struct ieee80211_tim_ie *) sp->tim;
- 		ise->se_dtimperiod = tim->tim_period;
- 	}
--	saveie(&ise->se_wme_ie, sp->wme);
--	saveie(&ise->se_wpa_ie, sp->wpa);
--	saveie(&ise->se_rsn_ie, sp->rsn);
--	saveie(&ise->se_ath_ie, sp->ath);
-+	saveie(&ise->se_wme_ie, sp->wme, 0);
-+	saveie(&ise->se_wpa_ie, sp->wpa, !sp->isprobe);
-+	saveie(&ise->se_rsn_ie, sp->rsn, !sp->isprobe);
-+	saveie(&ise->se_ath_ie, sp->ath, 0);
- 
- 	/* clear failure count after STA_FAIL_AGE passes */
- 	if (se->se_fails && (jiffies - se->se_lastfail) > STA_FAILS_AGE*HZ) {
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -3106,6 +3106,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 		 */
- 		IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
- 		memset(&scan, 0, sizeof(scan));
-+		scan.isprobe = (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) && IEEE80211_ADDR_EQ(wh->i_addr2, vap->iv_myaddr);
- 		scan.tstamp  = frm;
- 		frm += 8;
- 		scan.bintval = le16toh(*(__le16 *)frm);
---- a/net80211/ieee80211_scan.h
-+++ b/net80211/ieee80211_scan.h
-@@ -133,6 +133,7 @@ struct ieee80211_scanparams {
- 	u_int8_t erp;
- 	u_int16_t bintval;
- 	u_int8_t timoff;
-+	u_int8_t isprobe;
- 	u_int8_t *tim;
- 	u_int8_t *tstamp;
- 	u_int8_t *country;
diff --git a/package/madwifi/patches/369-mlme_assoc.patch b/package/madwifi/patches/369-mlme_assoc.patch
deleted file mode 100644
index 43aac668c3..0000000000
--- a/package/madwifi/patches/369-mlme_assoc.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -3723,6 +3723,7 @@ ieee80211_ioctl_setmlme(struct net_devic
- 		if (vap->iv_opmode == IEEE80211_M_STA) {
- 			struct scanlookup lookup;
- 
-+			preempt_scan(dev, 100, 100);
- 			lookup.se = NULL;
- 			lookup.mac = mlme->im_macaddr;
- 			/* XXX use revised api w/ explicit ssid */
diff --git a/package/madwifi/patches/370-wdsvap.patch b/package/madwifi/patches/370-wdsvap.patch
deleted file mode 100644
index 8a0e823ae8..0000000000
--- a/package/madwifi/patches/370-wdsvap.patch
+++ /dev/null
@@ -1,1665 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -124,7 +124,7 @@ enum {
- };
- 
- static struct ieee80211vap *ath_vap_create(struct ieee80211com *,
--	const char *, int, int, struct net_device *);
-+	const char *, int, int, struct net_device *, struct ieee80211vap *);
- static void ath_vap_delete(struct ieee80211vap *);
- static int ath_init(struct net_device *);
- static int ath_set_ack_bitrate(struct ath_softc *, int);
-@@ -1123,8 +1123,6 @@ ath_attach(u_int16_t devid, struct net_d
- 			autocreatemode = IEEE80211_M_IBSS;
- 		else if (!strcmp(autocreate, "ahdemo"))
- 			autocreatemode = IEEE80211_M_AHDEMO;
--		else if (!strcmp(autocreate, "wds"))
--			autocreatemode = IEEE80211_M_WDS;
- 		else if (!strcmp(autocreate, "monitor"))
- 			autocreatemode = IEEE80211_M_MONITOR;
- 		else {
-@@ -1137,7 +1135,7 @@ ath_attach(u_int16_t devid, struct net_d
- 	if (autocreatemode != -1) {
- 		rtnl_lock();
- 		vap = ieee80211_create_vap(ic, "ath%d", dev,
--				autocreatemode, 0);
-+				autocreatemode, 0, NULL);
- 		rtnl_unlock();
- 		if (vap == NULL)
- 			EPRINTF(sc, "Autocreation of %s VAP failed.", autocreate);
-@@ -1230,14 +1228,14 @@ ath_detach(struct net_device *dev)
- 
- static struct ieee80211vap *
- ath_vap_create(struct ieee80211com *ic, const char *name,
--	int opmode, int flags, struct net_device *mdev)
-+	int opmode, int flags, struct net_device *mdev, struct ieee80211vap *master)
- {
- 	struct ath_softc *sc = ic->ic_dev->priv;
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct net_device *dev;
- 	struct ath_vap *avp;
- 	struct ieee80211vap *vap;
--	int ic_opmode;
-+	int ic_opmode = IEEE80211_M_STA;
- 
- 	if (ic->ic_dev->flags & IFF_RUNNING) {
- 		/* needs to disable hardware too */
-@@ -1271,8 +1269,12 @@ ath_vap_create(struct ieee80211com *ic,
- 		} else
- 			ic_opmode = opmode;
- 		break;
--	case IEEE80211_M_HOSTAP:
- 	case IEEE80211_M_WDS:
-+		ic_opmode = ic->ic_opmode;
-+		if (!master)
-+			return NULL;
-+		break;
-+	case IEEE80211_M_HOSTAP:
- 		/* permit multiple APs and/or WDS links */
- 		/* XXX sta+ap for repeater/bridge application */
- 		if ((sc->sc_nvaps != 0) && (ic->ic_opmode == IEEE80211_M_STA))
-@@ -1304,7 +1306,7 @@ ath_vap_create(struct ieee80211com *ic,
- 	}
- 
- 	avp = dev->priv;
--	ieee80211_vap_setup(ic, dev, name, opmode, flags);
-+	ieee80211_vap_setup(ic, dev, name, opmode, flags, master);
- 	/* override with driver methods */
- 	vap = &avp->av_vap;
- 	avp->av_newstate = vap->iv_newstate;
-@@ -4209,8 +4211,7 @@ ath_calcrxfilter(struct ath_softc *sc)
- 	if (ic->ic_opmode == IEEE80211_M_STA ||
- 	    sc->sc_opmode == HAL_M_IBSS ||	/* NB: AHDEMO too */
- 	    (sc->sc_nostabeacons) || sc->sc_scanning ||
--		((ic->ic_opmode == IEEE80211_M_HOSTAP) &&
--		 (ic->ic_protmode != IEEE80211_PROT_NONE)))
-+		(ic->ic_opmode == IEEE80211_M_HOSTAP))
- 		rfilt |= HAL_RX_FILTER_BEACON;
- 	if (sc->sc_nmonvaps > 0)
- 		rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
-@@ -9032,8 +9033,6 @@ ath_calibrate(unsigned long arg)
- 		 * set sc->beacons if we might need to restart
-                  * them after ath_reset. */
- 		if (!sc->sc_beacons &&
--				(TAILQ_FIRST(&ic->ic_vaps)->iv_opmode != 
--				 IEEE80211_M_WDS) &&
- 				!txcont_was_active &&
- 				!sc->sc_dfs_cac) {
- 			sc->sc_beacons = 1;
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -373,10 +373,25 @@ void
- ieee80211_ifdetach(struct ieee80211com *ic)
- {
- 	struct ieee80211vap *vap;
-+	int count;
-+
-+	/* bring down all vaps */
-+	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+		ieee80211_stop(vap->iv_dev);
-+	}
-+
-+	/* wait for all subifs to disappear */
-+	do {
-+		schedule();
-+		rtnl_lock();
-+		count = ic->ic_subifs;
-+		rtnl_unlock();
-+	} while (count > 0);
- 
- 	rtnl_lock();
--	while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
-+	while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL) {
- 		ic->ic_vap_delete(vap);
-+	}
- 	rtnl_unlock();
- 
- 	del_timer(&ic->ic_dfs_excl_timer);
-@@ -396,7 +411,7 @@ EXPORT_SYMBOL(ieee80211_ifdetach);
- 
- int
- ieee80211_vap_setup(struct ieee80211com *ic, struct net_device *dev,
--	const char *name, int opmode, int flags)
-+	const char *name, int opmode, int flags, struct ieee80211vap *master)
- {
- #define	IEEE80211_C_OPMODE \
- 	(IEEE80211_C_IBSS | IEEE80211_C_HOSTAP | IEEE80211_C_AHDEMO | \
-@@ -510,9 +525,18 @@ ieee80211_vap_setup(struct ieee80211com
- 
- 	vap->iv_monitor_crc_errors = 0;
- 	vap->iv_monitor_phy_errors = 0;
-+	TAILQ_INIT(&vap->iv_wdslinks);
- 
--	IEEE80211_ADDR_COPY(vap->iv_myaddr, ic->ic_myaddr);
--	IEEE80211_ADDR_COPY(vap->iv_bssid, ic->ic_myaddr);
-+	if (master && (vap->iv_opmode == IEEE80211_M_WDS)) {
-+		vap->iv_master = master;
-+		TAILQ_INSERT_TAIL(&master->iv_wdslinks, vap, iv_wdsnext);
-+		/* use the same BSSID as the master interface */
-+		IEEE80211_ADDR_COPY(vap->iv_myaddr, vap->iv_master->iv_myaddr);
-+		IEEE80211_ADDR_COPY(vap->iv_bssid, vap->iv_master->iv_myaddr);
-+	} else {
-+		IEEE80211_ADDR_COPY(vap->iv_myaddr, ic->ic_myaddr);
-+		IEEE80211_ADDR_COPY(vap->iv_bssid, ic->ic_myaddr);
-+	}
- 	/* NB: Defer setting dev_addr so driver can override */
- 
- 	ieee80211_crypto_vattach(vap);
-@@ -547,7 +571,8 @@ ieee80211_vap_attach(struct ieee80211vap
- 	ifmedia_set(&vap->iv_media, imr.ifm_active);
- 
- 	IEEE80211_LOCK_IRQ(ic);
--	TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
-+	if (vap->iv_opmode != IEEE80211_M_WDS)
-+		TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
- 	IEEE80211_UNLOCK_IRQ(ic);
- 
- 	IEEE80211_ADDR_COPY(dev->dev_addr, vap->iv_myaddr);
-@@ -579,10 +604,27 @@ ieee80211_vap_detach(struct ieee80211vap
- {
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct net_device *dev = vap->iv_dev;
-+	struct ieee80211vap *avp;
-+
-+	/* Drop all WDS links that belong to this vap */
-+	while ((avp = TAILQ_FIRST(&vap->iv_wdslinks)) != NULL) {
-+		if (avp->iv_state != IEEE80211_S_INIT)
-+			ieee80211_stop(avp->iv_dev);
-+		ic->ic_vap_delete(avp);
-+	}
- 
- 	IEEE80211_CANCEL_TQUEUE(&vap->iv_stajoin1tq);
- 	IEEE80211_LOCK_IRQ(ic);
--	TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
-+	if (vap->iv_wdsnode) {
-+		vap->iv_wdsnode->ni_subif = NULL;
-+		ieee80211_unref_node(&vap->iv_wdsnode);
-+	}
-+	if ((vap->iv_opmode == IEEE80211_M_WDS) &&
-+		(vap->iv_master != NULL))
-+		TAILQ_REMOVE(&vap->iv_master->iv_wdslinks, vap, iv_wdsnext);
-+	else
-+		TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
-+
- 	if (TAILQ_EMPTY(&ic->ic_vaps))		/* reset to supported mode */
- 		ic->ic_opmode = IEEE80211_M_STA;
- 	IEEE80211_UNLOCK_IRQ(ic);
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -474,7 +474,7 @@ struct ieee80211req {
- #define	IEEE80211_IOC_DTIM_PERIOD	52	/* DTIM period (beacons) */
- #define	IEEE80211_IOC_BEACON_INTERVAL	53	/* beacon interval (ms) */
- #define	IEEE80211_IOC_ADDMAC		54	/* add sta to MAC ACL table */
--#define	IEEE80211_IOC_DELMAC		55	/* del sta from MAC ACL table */
-+#define	IEEE80211_IOC_SETMAC		55	/* set interface wds mac addr */
- #define	IEEE80211_IOC_FF		56	/* ATH fast frames (on, off) */
- #define	IEEE80211_IOC_TURBOP		57	/* ATH turbo' (on, off) */
- #define	IEEE80211_IOC_APPIEBUF		58	/* IE in the management frame */
-@@ -552,8 +552,8 @@ struct ieee80211req_scan_result {
- #define	IEEE80211_IOCTL_HALMAP		(SIOCIWFIRSTPRIV+21)
- #define	IEEE80211_IOCTL_ADDMAC		(SIOCIWFIRSTPRIV+22)
- #define	IEEE80211_IOCTL_DELMAC		(SIOCIWFIRSTPRIV+24)
--#define	IEEE80211_IOCTL_WDSADDMAC	(SIOCIWFIRSTPRIV+26)
--#define	IEEE80211_IOCTL_WDSDELMAC	(SIOCIWFIRSTPRIV+28)
-+#define	IEEE80211_IOCTL_WDSADDMAC	(SIOCIWFIRSTPRIV+25)
-+#define	IEEE80211_IOCTL_WDSSETMAC	(SIOCIWFIRSTPRIV+26)
- #define	IEEE80211_IOCTL_KICKMAC		(SIOCIWFIRSTPRIV+30)
- #define	IEEE80211_IOCTL_SETSCANLIST	(SIOCIWFIRSTPRIV+31)
- 
-@@ -649,6 +649,7 @@ enum {
- 	IEEE80211_PARAM_BGSCAN_THRESH		= 79,	/* bg scan rssi threshold */
- 	IEEE80211_PARAM_RSSI_DIS_THR	= 80,	/* rssi threshold for disconnection */
- 	IEEE80211_PARAM_RSSI_DIS_COUNT	= 81,	/* counter for rssi threshold */
-+	IEEE80211_PARAM_WDS_SEP			= 82,	/* move wds stations into separate interfaces */
- };
- 
- #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -81,6 +81,12 @@ set_quality(struct iw_quality *iq, u_int
- #endif
- }
- 
-+#ifndef container_of
-+#define container_of(ptr, type, member) ({          \
-+    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
-+	    (type *)( (char *)__mptr - offsetof(type,member) );})
-+#endif
-+
- /*
-  * Task deferral
-  *
-@@ -113,6 +119,29 @@ typedef void *IEEE80211_TQUEUE_ARG;
- 
- #define	IEEE80211_RESCHEDULE	schedule
- 
-+#include <linux/sched.h>
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41)
-+#include <linux/tqueue.h>
-+#define work_struct			tq_struct
-+#define schedule_work(t)		schedule_task((t))
-+#define flush_scheduled_work()		flush_scheduled_tasks()
-+#define IEEE80211_INIT_WORK(t, f) do { 			\
-+	memset((t), 0, sizeof(struct tq_struct)); \
-+	(t)->routine = (void (*)(void*)) (f); 	\
-+	(t)->data=(void *) (t);			\
-+} while (0)
-+#else
-+#include <linux/workqueue.h>
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-+#define IEEE80211_INIT_WORK(_t, _f)	INIT_WORK((_t), (void (*)(void *))(_f), (_t));
-+#else
-+#define IEEE80211_INIT_WORK(_t, _f)	INIT_WORK((_t), (_f));
-+#endif
-+
-+#endif /* KERNEL_VERSION < 2.5.41 */
-+
-+
- /* Locking */
- /* NB: beware, spin_is_locked() is not usefully defined for !(DEBUG || SMP)
-  * because spinlocks do not exist in this configuration. Instead IRQs 
-@@ -167,6 +196,14 @@ typedef spinlock_t ieee80211com_lock_t;
- 	IEEE80211_VAPS_LOCK_ASSERT(_ic);		\
- 	spin_unlock_bh(&(_ic)->ic_vapslock);		\
- } while (0)
-+#define	IEEE80211_VAPS_LOCK_IRQ(_ic) do {					\
-+	unsigned long __ilockflags;					\
-+	IEEE80211_VAPS_LOCK_CHECK(_ic);					\
-+	spin_lock_irqsave(&(_ic)->ic_vapslock, __ilockflags);
-+#define	IEEE80211_VAPS_UNLOCK_IRQ(_ic)					\
-+	IEEE80211_VAPS_LOCK_ASSERT(_ic);					\
-+	spin_unlock_irqrestore(&(_ic)->ic_vapslock, __ilockflags);	\
-+} while (0)
- 
- #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
- #define IEEE80211_VAPS_LOCK_ASSERT(_ic) \
-@@ -650,5 +687,5 @@ struct ifreq;
- int ieee80211_ioctl_create_vap(struct ieee80211com *, struct ifreq *,
- 	struct net_device *);
- struct ieee80211vap *ieee80211_create_vap(struct ieee80211com *, char *,
--	struct net_device *, int, int);
-+	struct net_device *, int, int, struct ieee80211vap *);
- #endif /* _NET80211_IEEE80211_LINUX_H_ */
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -187,6 +187,12 @@ struct ieee80211vap {
- 	struct ieee80211_proc_entry *iv_proc_entries;
- 	struct vlan_group *iv_vlgrp;			/* vlan group state */
- 
-+	/* list of wds links */
-+	TAILQ_HEAD(, ieee80211vap) iv_wdslinks;
-+	TAILQ_ENTRY(ieee80211vap) iv_wdsnext;
-+	struct ieee80211vap *iv_master;
-+	struct ieee80211_node *iv_wdsnode;
-+
- 	TAILQ_ENTRY(ieee80211vap) iv_next;		/* list of vap instances */
- 	struct ieee80211com *iv_ic;			/* back ptr to common state */
- 	u_int32_t iv_debug;				/* debug msg flags */
-@@ -316,6 +322,7 @@ struct ieee80211com {
- 	u_int8_t ic_myaddr[IEEE80211_ADDR_LEN];
- 	struct timer_list ic_inact;		/* mgmt/inactivity timer */
- 
-+	unsigned int ic_subifs;
- 	u_int32_t ic_flags;			/* state flags */
- 	u_int32_t ic_flags_ext;			/* extension of state flags */
- 	u_int32_t ic_caps;			/* capabilities */
-@@ -447,7 +454,7 @@ struct ieee80211com {
- 	atomic_t ic_node_counter;
- 	/* Virtual AP create/delete */
- 	struct ieee80211vap *(*ic_vap_create)(struct ieee80211com *,
--		const char *, int, int, struct net_device *);
-+		const char *, int, int, struct net_device *, struct ieee80211vap *);
- 	void (*ic_vap_delete)(struct ieee80211vap *);
- 
- 	/* Send/recv 802.11 management frame */
-@@ -619,6 +626,7 @@ MALLOC_DECLARE(M_80211_VAP);
- #define IEEE80211_FEXT_DROPUNENC_EAPOL	0x00000800	/* CONF: drop unencrypted eapol frames */
- #define IEEE80211_FEXT_APPIE_UPDATE	0x00001000	/* STATE: beacon APP IE updated */
- #define IEEE80211_FEXT_BGSCAN_THR	0x00002000	/* bgscan due to low rssi */
-+#define IEEE80211_FEXT_WDSSEP		0x00004000	/* move wds clients into separate interfaces */
- 
- #define IEEE80211_COM_UAPSD_ENABLE(_ic)		((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD)
- #define IEEE80211_COM_UAPSD_DISABLE(_ic)	((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD)
-@@ -703,7 +711,7 @@ MALLOC_DECLARE(M_80211_VAP);
- int ieee80211_ifattach(struct ieee80211com *);
- void ieee80211_ifdetach(struct ieee80211com *);
- int ieee80211_vap_setup(struct ieee80211com *, struct net_device *,
--	const char *, int, int);
-+	const char *, int, int, struct ieee80211vap *);
- int ieee80211_vap_attach(struct ieee80211vap *, ifm_change_cb_t, ifm_stat_cb_t);
- void ieee80211_vap_detach(struct ieee80211vap *);
- void ieee80211_mark_dfs(struct ieee80211com *, struct ieee80211_channel *);
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2190,7 +2190,7 @@ ieee80211_setupxr(struct ieee80211vap *v
- 			ieee80211_scan_flush(ic);	/* NB: could optimize */
- 
- 			if (!(xrvap = ic->ic_vap_create(ic, name, IEEE80211_M_HOSTAP,
--				IEEE80211_VAP_XR | IEEE80211_CLONE_BSSID, dev)))
-+				IEEE80211_VAP_XR | IEEE80211_CLONE_BSSID, dev, NULL)))
- 				return;
- 
- 			/* We use iv_xrvap to link to the parent VAP as well */
-@@ -2867,6 +2867,14 @@ ieee80211_ioctl_setparam(struct net_devi
- 		else
- 			vap->iv_minrateindex = 0;
- 		break;
-+	case IEEE80211_PARAM_WDS_SEP:
-+		if (vap->iv_opmode != IEEE80211_M_HOSTAP)
-+			retv = -EINVAL;
-+		else if (value)
-+			vap->iv_flags_ext |= IEEE80211_FEXT_WDSSEP;
-+		else
-+			vap->iv_flags_ext &= ~IEEE80211_FEXT_WDSSEP;
-+		break;
- #ifdef ATH_REVERSE_ENGINEERING
- 	case IEEE80211_PARAM_DUMPREGS:
- 		ieee80211_dump_registers(dev, info, w, extra);
-@@ -3223,6 +3231,9 @@ ieee80211_ioctl_getparam(struct net_devi
- 	case IEEE80211_PARAM_MINRATE:
- 		param[0] = vap->iv_minrateindex;
- 		break;
-+	case IEEE80211_PARAM_WDS_SEP:
-+		param[0] = !!(vap->iv_flags_ext & IEEE80211_FEXT_WDSSEP);
-+		break;
- 	default:
- 		return -EOPNOTSUPP;
- 	}
-@@ -3801,74 +3812,54 @@ ieee80211_ioctl_setmlme(struct net_devic
- 	return 0;
- }
- 
-+#define WDSNAME ".wds%d"
- static int
--ieee80211_ioctl_wdsmac(struct net_device *dev, struct iw_request_info *info,
-+ieee80211_ioctl_wdsaddmac(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
- 	struct ieee80211vap *vap = dev->priv;
- 	struct sockaddr *sa = (struct sockaddr *)extra;
-+	struct ieee80211com *ic = vap->iv_ic;
-+	struct ieee80211vap *avp;
-+	char *name;
- 
--	if (!IEEE80211_ADDR_NULL(vap->wds_mac)) {
--		printk("%s: Failed to add WDS MAC: " MAC_FMT "\n", dev->name,
--			MAC_ADDR(sa->sa_data));
--		printk("%s: Device already has WDS mac address attached,"
--			" remove first\n", dev->name);
--		return -1;
--	}
--
--	memcpy(vap->wds_mac, sa->sa_data, IEEE80211_ADDR_LEN);
-+	if (vap->iv_opmode != IEEE80211_M_HOSTAP)
-+		return -EINVAL;
- 
--	printk("%s: Added WDS MAC: " MAC_FMT "\n", dev->name,
--		MAC_ADDR(vap->wds_mac));
-+	name = kmalloc(strlen(vap->iv_dev->name) + sizeof(WDSNAME) + 1, GFP_KERNEL);
-+	if (!name)
-+		return -ENOMEM;
- 
--	if (IS_UP(vap->iv_dev)) {
--		/* Force us back to scan state to force us to go back through RUN
--		 * state and create/pin the WDS peer node into memory. */
--		return ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
--	}
-+	strcpy(name, vap->iv_dev->name);
-+	strcat(name, WDSNAME);
-+	avp = ieee80211_create_vap(ic, name, ic->ic_dev, IEEE80211_M_WDS, 0, vap);
-+	kfree(name);
-+	if (!avp)
-+		return -ENOMEM;
- 
-+	memcpy(avp->wds_mac, sa->sa_data, IEEE80211_ADDR_LEN);
- 	return 0;
- }
-+#undef WDSNAME
- 
- static int
--ieee80211_ioctl_wdsdelmac(struct net_device *dev, struct iw_request_info *info,
-+ieee80211_ioctl_wdssetmac(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
- 	struct ieee80211vap *vap = dev->priv;
- 	struct sockaddr *sa = (struct sockaddr *)extra;
--	struct ieee80211com *ic = vap->iv_ic;
--	struct ieee80211_node *wds_ni;
- 
--	/* WDS Mac address filed already? */
--	if (IEEE80211_ADDR_NULL(vap->wds_mac))
--		return 0;
-+	if (vap->iv_opmode != IEEE80211_M_WDS)
-+		return -EINVAL;
- 
--	/* Compare suplied MAC address with WDS MAC of this interface 
--	 * remove when mac address is known
--	 */
--	if (memcmp(vap->wds_mac, sa->sa_data, IEEE80211_ADDR_LEN) == 0) {
--		if (IS_UP(vap->iv_dev)) {
--			wds_ni = ieee80211_find_txnode(vap, vap->wds_mac);
--			if (wds_ni != NULL) {
--				/* Release reference created by find node */
--				ieee80211_unref_node(&wds_ni);
--				/* Release reference created by transition to RUN state,
--				 * [pinning peer node into the table] */
--				ieee80211_unref_node(&wds_ni);
--			}
--		}
--		memset(vap->wds_mac, 0x00, IEEE80211_ADDR_LEN);
--		if (IS_UP(vap->iv_dev)) {
--			/* This leaves a dead WDS node, until started again */
--			return ic->ic_reset(ic->ic_dev);
--		}
--		return 0;
-+	memcpy(vap->wds_mac, sa->sa_data, IEEE80211_ADDR_LEN);
-+	if (IS_UP(vap->iv_dev)) {
-+		/* Force us back to scan state to force us to go back through RUN
-+		 * state and create/pin the WDS peer node into memory. */
-+		return ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
- 	}
- 
--	printk("%s: WDS MAC address " MAC_FMT " is not known by this interface\n",
--		dev->name, MAC_ADDR(sa->sa_data));
--
--	return -1;
-+	return 0;
- }
- 
- /*
-@@ -4470,6 +4461,8 @@ get_sta_space(void *arg, struct ieee8021
- 	struct ieee80211vap *vap = ni->ni_vap;
- 	size_t ielen;
- 
-+	if (req->vap->iv_wdsnode && ni->ni_subif)
-+		vap = ni->ni_subif;
- 	if (vap != req->vap && vap != req->vap->iv_xrvap)	/* only entries for this vap */
- 		return;
- 	if ((vap->iv_opmode == IEEE80211_M_HOSTAP ||
-@@ -4489,6 +4482,8 @@ get_sta_info(void *arg, struct ieee80211
- 	size_t ielen, len;
- 	u_int8_t *cp;
- 
-+	if (req->vap->iv_wdsnode && ni->ni_subif)
-+		vap = ni->ni_subif;
- 	if (vap != req->vap && vap != req->vap->iv_xrvap)	/* only entries for this vap (or) xrvap */
- 		return;
- 	if ((vap->iv_opmode == IEEE80211_M_HOSTAP ||
-@@ -5391,8 +5386,8 @@ static const struct iw_priv_args ieee802
- 	  IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "kickmac"},
- 	{ IEEE80211_IOCTL_WDSADDMAC,
- 	  IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0,"wds_add" },
--	{ IEEE80211_IOCTL_WDSDELMAC,
--	  IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0,"wds_del" },
-+	{ IEEE80211_IOCTL_WDSSETMAC,
-+	  IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0,"wds_set" },
- 	{ IEEE80211_IOCTL_SETCHANLIST,
- 	  IW_PRIV_TYPE_CHANLIST | IW_PRIV_SIZE_FIXED, 0,"setchanlist" },
- 	{ IEEE80211_IOCTL_GETCHANLIST,
-@@ -5790,6 +5785,10 @@ static const struct iw_priv_args ieee802
- 	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"},
- 	{ IEEE80211_IOCTL_SETSCANLIST,
- 	 IW_PRIV_TYPE_CHAR | 255, 0, "setscanlist"},
-+	{ IEEE80211_PARAM_WDS_SEP,
-+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wdssep"},
-+	{ IEEE80211_PARAM_WDS_SEP,
-+	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_wdssep"},
- 
- #ifdef ATH_REVERSE_ENGINEERING
- 	/*
-@@ -5884,8 +5883,8 @@ static const iw_handler ieee80211_priv_h
- #endif
- 	set_priv(IEEE80211_IOCTL_ADDMAC, ieee80211_ioctl_addmac),
- 	set_priv(IEEE80211_IOCTL_DELMAC, ieee80211_ioctl_delmac),
--	set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac),
--	set_priv(IEEE80211_IOCTL_WDSDELMAC, ieee80211_ioctl_wdsdelmac),
-+	set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsaddmac),
-+	set_priv(IEEE80211_IOCTL_WDSSETMAC, ieee80211_ioctl_wdssetmac),
- 	set_priv(IEEE80211_IOCTL_KICKMAC, ieee80211_ioctl_kickmac),
- 	set_priv(IEEE80211_IOCTL_SETSCANLIST, ieee80211_ioctl_setscanlist),
- #ifdef ATH_REVERSE_ENGINEERING
-@@ -5913,6 +5912,8 @@ static int
- ieee80211_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
- 	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211com *ic = vap->iv_ic;
-+	struct ieee80211_node *ni;
- 
- 	switch (cmd) {
- 	case SIOCG80211STATS:
-@@ -5921,8 +5922,20 @@ ieee80211_ioctl(struct net_device *dev,
- 	case SIOC80211IFDESTROY:
- 		if (!capable(CAP_NET_ADMIN))
- 			return -EPERM;
-+		/* drop all node subifs */
-+		TAILQ_FOREACH(ni, &ic->ic_sta.nt_node, ni_list) {
-+			struct ieee80211vap *avp = ni->ni_subif;
-+
-+			if (ni->ni_vap != vap)
-+				continue;
-+			if (!avp)
-+				continue;
-+			ni->ni_subif = NULL;
-+			ieee80211_stop(avp->iv_dev);
-+			ic->ic_vap_delete(avp);
-+		}
- 		ieee80211_stop(vap->iv_dev);	/* force state before cleanup */
--		vap->iv_ic->ic_vap_delete(vap);
-+		ic->ic_vap_delete(vap);
- 		return 0;
- 	case IEEE80211_IOCTL_GETKEY:
- 		return ieee80211_ioctl_getkey(dev, (struct iwreq *) ifr);
-@@ -5956,7 +5969,7 @@ ieee80211_ioctl_create_vap(struct ieee80
- 
- 	strncpy(name, cp.icp_name, sizeof(name));
- 
--	vap = ieee80211_create_vap(ic, name, mdev, cp.icp_opmode, cp.icp_flags);
-+	vap = ieee80211_create_vap(ic, name, mdev, cp.icp_opmode, cp.icp_flags, NULL);
- 	if (vap == NULL)
- 		return -EIO;
- 
-@@ -5973,9 +5986,9 @@ EXPORT_SYMBOL(ieee80211_ioctl_create_vap
-  */
- struct ieee80211vap*
- ieee80211_create_vap(struct ieee80211com *ic, char *name,
--	struct net_device *mdev, int opmode, int opflags)
-+	struct net_device *mdev, int opmode, int opflags, struct ieee80211vap *master)
- {
--	return ic->ic_vap_create(ic, name, opmode, opflags, mdev);
-+	return ic->ic_vap_create(ic, name, opmode, opflags, mdev, master);
- }
- EXPORT_SYMBOL(ieee80211_create_vap);
- 
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -199,8 +199,10 @@ ieee80211_input(struct ieee80211vap * va
- {
- #define	HAS_SEQ(type)	((type & 0x4) == 0)
- 	struct ieee80211_node * ni = ni_or_null;
--	struct ieee80211com *ic = vap->iv_ic;
--	struct net_device *dev = vap->iv_dev;
-+	struct ieee80211com *ic;
-+	struct net_device *dev;
-+	struct ieee80211_node *ni_wds = NULL;
-+	struct net_device_stats *stats;
- 	struct ieee80211_frame *wh;
- 	struct ieee80211_key *key;
- 	struct ether_header *eh;
-@@ -212,6 +214,19 @@ ieee80211_input(struct ieee80211vap * va
- 	u_int8_t *bssid;
- 	u_int16_t rxseq;
- 
-+	type = -1;			/* undefined */
-+
-+	if (!vap)
-+		goto out;
-+
-+	ic = vap->iv_ic;
-+	if (!ic)
-+		goto out;
-+
-+	dev = vap->iv_dev;
-+	if (!dev)
-+		goto out;
-+
- 	/* initialize ni as in the previous API */
- 	if (ni_or_null == NULL) {
-                /* This function does not 'own' vap->iv_bss, so we cannot
-@@ -227,7 +242,6 @@ ieee80211_input(struct ieee80211vap * va
- 
- 	/* XXX adjust device in sk_buff? */
- 
--	type = -1;			/* undefined */
- 	/*
- 	 * In monitor mode, send everything directly to bpf.
- 	 * Also do not process frames w/o i_addr2 any further.
-@@ -434,7 +448,7 @@ ieee80211_input(struct ieee80211vap * va
- 
- 	switch (type) {
- 	case IEEE80211_FC0_TYPE_DATA:
--		hdrspace = ieee80211_hdrspace(ic, wh);
-+		hdrspace = ieee80211_hdrsize(wh);
- 		if (skb->len < hdrspace) {
- 			IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
- 				wh, "data", "too short: len %u, expecting %u",
-@@ -444,16 +458,24 @@ ieee80211_input(struct ieee80211vap * va
- 		}
- 		switch (vap->iv_opmode) {
- 		case IEEE80211_M_STA:
--			if ((dir != IEEE80211_FC1_DIR_FROMDS) &&
--			    (!((vap->iv_flags_ext & IEEE80211_FEXT_WDS) &&
--			    (dir == IEEE80211_FC1_DIR_DSTODS)))) {
-+			switch(dir) {
-+			case IEEE80211_FC1_DIR_FROMDS:
-+				break;
-+			case IEEE80211_FC1_DIR_DSTODS:
-+				if (vap->iv_flags_ext & IEEE80211_FEXT_WDS)
-+					break;
-+			default:
- 				IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
- 					wh, "data", "invalid dir 0x%x", dir);
- 				vap->iv_stats.is_rx_wrongdir++;
- 				goto out;
- 			}
- 
--	        	if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-+			if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-+				/* ignore 3-addr mcast if we're WDS STA */
-+				if (vap->iv_flags_ext & IEEE80211_FEXT_WDS)
-+					goto out;
-+
- 				/* Discard multicast if IFF_MULTICAST not set */
- 				if ((0 != memcmp(wh->i_addr3, dev->broadcast, ETH_ALEN)) && 
- 					(0 == (dev->flags & IFF_MULTICAST))) {
-@@ -481,24 +503,10 @@ ieee80211_input(struct ieee80211vap * va
- 					vap->iv_stats.is_rx_mcastecho++;
- 					goto out;
- 				}
--				/* 
--				 * if it is brodcasted by me on behalf of
--				 * a station behind me, drop it.
--				 */
--				if (vap->iv_flags_ext & IEEE80211_FEXT_WDS) {
--					struct ieee80211_node_table *nt;
--					struct ieee80211_node *ni_wds;
--					nt = &ic->ic_sta;
--					ni_wds = ieee80211_find_wds_node(nt, wh->i_addr3);
--					if (ni_wds) {
--						ieee80211_unref_node(&ni_wds);
--						IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
--							wh, NULL, "%s",
--							"multicast echo originated from node behind me");
--						vap->iv_stats.is_rx_mcastecho++;
--						goto out;
--					}
--				}
-+			} else {
-+				/* Same BSSID, but not meant for us to receive */
-+				if (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr))
-+					goto out;
- 			}
- 			break;
- 		case IEEE80211_M_IBSS:
-@@ -540,16 +548,28 @@ ieee80211_input(struct ieee80211vap * va
- 				vap->iv_stats.is_rx_notassoc++;
- 				goto err;
- 			}
-+
- 			/*
- 			 * If we're a 4 address packet, make sure we have an entry in
- 			 * the node table for the packet source address (addr4).
- 			 * If not, add one.
- 			 */
-+			/* check for wds link first */
-+			if ((dir == IEEE80211_FC1_DIR_DSTODS) && !ni->ni_subif) {
-+				if (vap->iv_flags_ext & IEEE80211_FEXT_WDSSEP) {
-+					ieee80211_wds_addif(ni);
-+					/* we must drop frames here until the interface has
-+					 * been fully separated, otherwise a bridge might get
-+					 * confused */
-+					goto err;
-+				}
-+			}
-+
- 			/* XXX: Useless node mgmt API; make better */
--			if (dir == IEEE80211_FC1_DIR_DSTODS) {
--				struct ieee80211_node_table *nt;
-+			if ((dir == IEEE80211_FC1_DIR_DSTODS) && !vap->iv_wdsnode &&
-+					!ni_wds && !ni->ni_subif) {
-+				struct ieee80211_node_table *nt = &ic->ic_sta;
- 				struct ieee80211_frame_addr4 *wh4;
--				struct ieee80211_node *ni_wds;
- 
- 				if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS)) {
- 					IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
-@@ -557,7 +577,6 @@ ieee80211_input(struct ieee80211vap * va
- 					goto err;
- 				}
- 				wh4 = (struct ieee80211_frame_addr4 *)skb->data;
--				nt = &ic->ic_sta;
- 				ni_wds = ieee80211_find_wds_node(nt, wh4->i_addr4);
- 				/* Last call increments ref count if !NULL */
- 				if ((ni_wds != NULL) && (ni_wds != ni)) {
-@@ -608,6 +627,11 @@ ieee80211_input(struct ieee80211vap * va
- 			goto out;
- 		}
- 
-+		/* check if there is any data left */
-+		hdrspace = ieee80211_hdrspace(ic, wh);
-+		if (skb->len < hdrspace)
-+			goto out;
-+
- 		/*
- 		 * Handle privacy requirements.  Note that we
- 		 * must not be preempted from here until after
-@@ -680,8 +704,12 @@ ieee80211_input(struct ieee80211vap * va
- 		if (! accept_data_frame(vap, ni, key, skb, eh))
- 			goto out;
- 
--		vap->iv_devstats.rx_packets++;
--		vap->iv_devstats.rx_bytes += skb->len;
-+		if (ni->ni_subif && ((eh)->ether_type != __constant_htons(ETHERTYPE_PAE)))
-+			stats = &ni->ni_subif->iv_devstats;
-+		else
-+			stats = &vap->iv_devstats;
-+		stats->rx_packets++;
-+		stats->rx_bytes += skb->len;
- 		IEEE80211_NODE_STAT(ni, rx_data);
- 		IEEE80211_NODE_STAT_ADD(ni, rx_bytes, skb->len);
- 		ic->ic_lastdata = jiffies;
-@@ -1114,6 +1142,18 @@ ieee80211_deliver_data(struct ieee80211_
- 		dev = vap->iv_xrvap->iv_dev;
- #endif
- 
-+	/* if the node has a wds subif, move data frames there,
-+	 * but keep EAP traffic on the master */
-+	if (ni->ni_subif && ((eh)->ether_type != __constant_htons(ETHERTYPE_PAE))) {
-+		if (ni->ni_vap == ni->ni_subif) {
-+			ieee80211_dev_kfree_skb(&skb);
-+			return;
-+		} else {
-+			vap = ni->ni_subif;
-+			dev = vap->iv_dev;
-+		}
-+	}
-+
- 	/* perform as a bridge within the vap */
- 	/* XXX intra-vap bridging only */
- 	if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
-@@ -1139,7 +1179,16 @@ ieee80211_deliver_data(struct ieee80211_
- 			if (ni1 != NULL) {
- 				if (ni1->ni_vap == vap &&
- 				    ieee80211_node_is_authorized(ni1) &&
-+					!ni1->ni_subif &&
- 				    ni1 != vap->iv_bss) {
-+
-+					/* tried to bridge to a subif, drop the packet */
-+					if (ni->ni_subif) {
-+						ieee80211_unref_node(&ni1);
-+						ieee80211_dev_kfree_skb(&skb);
-+						return;
-+					}
-+
- 					skb1 = skb;
- 					skb = NULL;
- 				}
-@@ -3084,8 +3133,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 		    (vap->iv_opmode == IEEE80211_M_STA && ni->ni_associd) ||
- 		    (vap->iv_opmode == IEEE80211_M_IBSS) ||
- 			((subtype == IEEE80211_FC0_SUBTYPE_BEACON) &&
--			 (vap->iv_opmode == IEEE80211_M_HOSTAP) &&
--			 (ic->ic_protmode != IEEE80211_PROT_NONE)))) {
-+			 (vap->iv_opmode == IEEE80211_M_HOSTAP)))) {
- 			vap->iv_stats.is_rx_mgtdiscard++;
- 			return;
- 		}
-@@ -3471,13 +3519,56 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 		 */
- 		if (ic->ic_flags & IEEE80211_F_SCAN) {
- 			ieee80211_add_scan(vap, &scan, wh, subtype, rssi, rtsf);
--			return;
- 		}
--		if ((vap->iv_opmode == IEEE80211_M_IBSS) && 
--				(scan.capinfo & IEEE80211_CAPINFO_IBSS)) {
-+		/* NB: Behavior of WDS-Link and Ad-Hoc is very similar here:
-+		 * When we receive a beacon that belongs to the AP that we're
-+		 * connected to, use it to refresh the local node info.
-+		 * If no node is found, go through the vap's wds link table
-+		 * and try to find the sub-vap that is interested in this address
-+		 */
-+		if (((vap->iv_opmode == IEEE80211_M_IBSS) &&
-+				(scan.capinfo & IEEE80211_CAPINFO_IBSS)) ||
-+				(((vap->iv_opmode == IEEE80211_M_HOSTAP) ||
-+				 (vap->iv_opmode == IEEE80211_M_WDS)) &&
-+				(scan.capinfo & IEEE80211_CAPINFO_ESS))) {
-+			struct ieee80211vap *avp = NULL;
-+			int found = 0;
-+
-+			IEEE80211_LOCK_IRQ(vap->iv_ic);
-+			if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
-+				TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
-+					if (!memcmp(avp->wds_mac, wh->i_addr2, IEEE80211_ADDR_LEN)) {
-+						if (avp->iv_state != IEEE80211_S_RUN)
-+							continue;
-+						if (!avp->iv_wdsnode)
-+							continue;
-+						found = 1;
-+						break;
-+					}
-+				}
-+				if (found)
-+					ni = ni_or_null = avp->iv_wdsnode;
-+			} else if ((vap->iv_opmode == IEEE80211_M_WDS) && vap->iv_wdsnode) {
-+				found = 1;
-+				ni = ni_or_null = vap->iv_wdsnode;
-+			}
-+			IEEE80211_UNLOCK_IRQ(vap->iv_ic);
-+
-+			if (!found)
-+				break;
-+
- 			if (ni_or_null == NULL) {
--				/* Create a new entry in the neighbor table. */
--				ni = ieee80211_add_neighbor(vap, wh, &scan);
-+				if (avp) {
-+					IEEE80211_LOCK_IRQ(ic);
-+					ni = ieee80211_add_neighbor(avp, wh, &scan);
-+					/* force assoc */
-+					ni->ni_associd |= 0xc000;
-+					avp->iv_wdsnode = ieee80211_ref_node(ni);
-+					IEEE80211_UNLOCK_IRQ(ic);
-+				} else if (vap->iv_opmode == IEEE80211_M_IBSS) {
-+					/* Create a new entry in the neighbor table. */
-+					ni = ieee80211_add_neighbor(vap, wh, &scan);
-+				}
- 			} else {
- 				/*
- 				 * Copy data from beacon to neighbor table.
-@@ -3490,6 +3581,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 				IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
- 				memcpy(ni->ni_tstamp.data, scan.tstamp,
- 					sizeof(ni->ni_tstamp));
-+				ni->ni_inact = ni->ni_inact_reload;
- 				ni->ni_intval = 
- 					IEEE80211_BINTVAL_SANITISE(scan.bintval);
- 				ni->ni_capinfo = scan.capinfo;
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -47,6 +47,7 @@
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
- #include <linux/random.h>
-+#include <linux/rtnetlink.h>
- 
- #include "if_media.h"
- 
-@@ -236,7 +237,11 @@ void
- ieee80211_node_vdetach(struct ieee80211vap *vap)
- {
- 	struct ieee80211com *ic = vap->iv_ic;
-+	struct ieee80211_node *ni;
- 
-+	ni = vap->iv_wdsnode;
-+	if (ni)
-+		ni->ni_subif = NULL;
- 	ieee80211_node_table_reset(&ic->ic_sta, vap);
- 	if (vap->iv_bss != NULL) {
- 		ieee80211_unref_node(&vap->iv_bss);
-@@ -309,7 +314,7 @@ ieee80211_create_ibss(struct ieee80211va
- 	/* Check to see if we already have a node for this mac
- 	 * NB: we gain a node reference here
- 	 */
--	ni = ieee80211_find_node(&ic->ic_sta, vap->iv_myaddr);
-+	ni = ieee80211_find_txnode(vap, vap->iv_myaddr);
- 	if (ni == NULL) {
- 		ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr);
- 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
-@@ -831,12 +836,18 @@ node_table_leave_locked(struct ieee80211
- 		LIST_REMOVE(ni, ni_hash);
- 	}
- 	ni->ni_table = NULL;
-+	if (ni->ni_vap->iv_wdsnode == ni) {
-+#ifdef IEEE80211_DEBUG_REFCNT
-+		ieee80211_unref_node_debug(&ni->ni_vap->iv_wdsnode, func, line);
-+#else
-+		ieee80211_unref_node(&ni->ni_vap->iv_wdsnode);
-+#endif
-+	}
- #ifdef IEEE80211_DEBUG_REFCNT
- 	ieee80211_unref_node_debug(&ni, func, line);
- #else
- 	ieee80211_unref_node(&ni);
- #endif
--	
- }
- 
- /* This is overridden by ath_node_alloc in ath/if_ath.c, and so
-@@ -1134,6 +1145,65 @@ ieee80211_alloc_node(struct ieee80211vap
- 	return ni;
- }
- 
-+#define WDSIFNAME ".sta%d"
-+static void
-+ieee80211_wds_do_addif(struct work_struct *work)
-+{
-+	struct ieee80211_node *ni = container_of(work, struct ieee80211_node, ni_create);
-+	struct ieee80211vap *vap = ni->ni_vap;
-+	struct ieee80211com *ic = vap->iv_ic;
-+	struct ieee80211vap *avp = NULL;
-+	char *name;
-+
-+	rtnl_lock();
-+	/* did we get cancelled by the destroy call? */
-+	if (!ni->ni_subif)
-+		goto done;
-+
-+	ni->ni_subif = NULL;
-+	name = kmalloc(strlen(vap->iv_dev->name) + sizeof(WDSIFNAME) + 1, GFP_KERNEL);
-+	if (!name)
-+		goto done;
-+
-+	strcpy(name, vap->iv_dev->name);
-+	strcat(name, WDSIFNAME);
-+	avp = ieee80211_create_vap(ic, name, ic->ic_dev, IEEE80211_M_WDS, 0, vap);
-+	kfree(name);
-+	if (!avp)
-+		goto done;
-+
-+	memcpy(avp->wds_mac, ni->ni_bssid, IEEE80211_ADDR_LEN);
-+	avp->iv_wdsnode = ieee80211_ref_node(ni);
-+	ni->ni_subif = avp;
-+	ic->ic_subifs++;
-+
-+done:
-+	if (avp) {
-+		IEEE80211_VAPS_LOCK_IRQ(ic);
-+		avp->iv_newstate(vap, IEEE80211_S_RUN, -1);
-+		IEEE80211_VAPS_UNLOCK_IRQ(ic);
-+	}
-+	rtnl_unlock();
-+	ieee80211_unref_node(&ni);
-+}
-+#undef WDSIFNAME
-+
-+void ieee80211_wds_addif(struct ieee80211_node *ni)
-+{
-+	/* check if the node is split out already,
-+	 * or if we're in progress of setting up a new interface already */
-+	if (ni->ni_subif)
-+		return;
-+
-+	if (!ni->ni_table)
-+		return;
-+
-+	ieee80211_ref_node(ni);
-+	ni->ni_subif = ni->ni_vap;
-+	IEEE80211_INIT_WORK(&ni->ni_create, ieee80211_wds_do_addif);
-+	schedule_work(&ni->ni_create);
-+}
-+
- /* Add wds address to the node table */
- int
- #ifdef IEEE80211_DEBUG_REFCNT
-@@ -1553,22 +1623,39 @@ ieee80211_find_rxnode(struct ieee80211co
- 	((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL)
- 	struct ieee80211_node_table *nt;
- 	struct ieee80211_node *ni;
-+	struct ieee80211vap *vap, *avp;
-+	const u_int8_t *addr;
-+
-+	if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/)
-+		addr = wh->i_addr1;
-+	else
-+		addr = wh->i_addr2;
-+
-+	if (IEEE80211_IS_MULTICAST(addr))
-+		return NULL;
- 
- 	/* XXX check ic_bss first in station mode */
- 	/* XXX 4-address frames? */
- 	nt = &ic->ic_sta;
- 	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
--	if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/)
--#ifdef IEEE80211_DEBUG_REFCNT
--		ni = ieee80211_find_node_locked_debug(nt, wh->i_addr1, func, line);
--#else
--		ni = ieee80211_find_node_locked(nt, wh->i_addr1);
--#endif
--	else
-+	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) {
-+		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+			TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
-+				if (!IEEE80211_ADDR_EQ(addr, avp->wds_mac))
-+					continue;
-+
-+				if (avp->iv_wdsnode)
-+					return ieee80211_ref_node(avp->iv_wdsnode);
-+				else
-+					return NULL;
-+			}
-+		}
-+	}
-+
- #ifdef IEEE80211_DEBUG_REFCNT
--		ni = ieee80211_find_node_locked_debug(nt, wh->i_addr2, func, line);
-+	ni = ieee80211_find_node_locked_debug(nt, addr, func, line);
- #else
--		ni = ieee80211_find_node_locked(nt, wh->i_addr2);
-+	ni = ieee80211_find_node_locked(nt, addr);
- #endif
- 	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
- 
-@@ -1596,9 +1683,19 @@ ieee80211_find_txnode_debug(struct ieee8
- ieee80211_find_txnode(struct ieee80211vap *vap, const u_int8_t *mac)
- #endif
- {
-+	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_node_table *nt;
- 	struct ieee80211_node *ni = NULL;
- 
-+	IEEE80211_LOCK_IRQ(ic);
-+	if (vap->iv_opmode == IEEE80211_M_WDS) {
-+		if (vap->iv_wdsnode && (vap->iv_state == IEEE80211_S_RUN))
-+			return ieee80211_ref_node(vap->iv_wdsnode);
-+		else
-+			return NULL;
-+	}
-+	IEEE80211_UNLOCK_IRQ(ic);
-+
- 	/*
- 	 * The destination address should be in the node table
- 	 * unless we are operating in station mode or this is a
-@@ -1669,6 +1766,11 @@ ieee80211_free_node(struct ieee80211_nod
- {
- 	struct ieee80211vap *vap = ni->ni_vap;
- 
-+	IEEE80211_LOCK_IRQ(ni->ni_ic);
-+	if (vap && ni == vap->iv_wdsnode)
-+		vap->iv_wdsnode = NULL;
-+	IEEE80211_UNLOCK_IRQ(ni->ni_ic);
-+
- 	atomic_dec(&ni->ni_ic->ic_node_counter);
- 	node_print_message(IEEE80211_MSG_NODE|IEEE80211_MSG_NODE_REF,
- 			   1 /* show counter */, 
-@@ -1781,22 +1883,6 @@ restart:
- 		    jiffies > ni->ni_rxfragstamp + HZ) {
- 			ieee80211_dev_kfree_skb(&ni->ni_rxfrag);
- 		}
--		/*
--		 * Special case ourself; we may be idle for extended periods
--		 * of time and regardless reclaiming our state is wrong.
--		 * Special case a WDS link: it may be dead or idle, but it is 
--		 * never ok to reclaim it, as this will block transmissions
--		 * and nobody will recreate the node when the WDS peer is
--		 * available again. */
--		if ((ni == ni->ni_vap->iv_bss) ||
--		    (ni->ni_vap->iv_opmode == IEEE80211_M_WDS && 
--		     !memcmp(ni->ni_macaddr, ni->ni_vap->wds_mac, ETH_ALEN)))
--		{
--			/* NB: don't permit it to go negative */
--			if (ni->ni_inact > 0)
--				ni->ni_inact--;
--			continue;
--		}
- 		ni->ni_inact--;
- 		if (ni->ni_associd != 0 || isadhoc) {
- 			struct ieee80211vap *vap = ni->ni_vap;
-@@ -2263,6 +2349,35 @@ ieee80211_node_leave_11g(struct ieee8021
- 	}
- }
- 
-+static void
-+ieee80211_subif_destroy(struct work_struct *work)
-+{
-+	struct ieee80211_node *ni = container_of(work, struct ieee80211_node, ni_destroy);
-+	struct ieee80211vap *vap;
-+	struct ieee80211com *ic;
-+
-+	/* wait for full initialization before we start the teardown
-+	 * otherwise we could leak interfaces */
-+	while (ni->ni_subif == ni->ni_vap)
-+		schedule();
-+
-+	rtnl_lock();
-+	vap = ni->ni_subif;
-+
-+	if (!vap)
-+		goto done;
-+
-+	ic = vap->iv_ic;
-+	ni->ni_subif = NULL;
-+	ieee80211_stop(vap->iv_dev);
-+	ic->ic_vap_delete(vap);
-+	ic->ic_subifs--;
-+
-+done:
-+	ieee80211_unref_node(&ni);
-+	rtnl_unlock();
-+}
-+
- /*
-  * Handle bookkeeping for a station/neighbor leaving
-  * the bss when operating in ap or adhoc modes.
-@@ -2279,6 +2394,12 @@ ieee80211_node_leave(struct ieee80211_no
- 			ni, "station with aid %d leaves (refcnt %u)",
- 			IEEE80211_NODE_AID(ni), atomic_read(&ni->ni_refcnt));
- 
-+	if (ni->ni_subif) {
-+		ieee80211_ref_node(ni);
-+		IEEE80211_INIT_WORK(&ni->ni_destroy, ieee80211_subif_destroy);
-+		schedule_work(&ni->ni_destroy);
-+	}
-+
- 	/* From this point onwards we can no longer find the node,
- 	 * so no more references are generated
- 	 */
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -246,15 +246,16 @@ ieee80211_hardstart(struct sk_buff *skb,
- 	 * things like power save.
- 	 */
- 	eh = (struct ether_header *)skb->data;
--	if (vap->iv_opmode == IEEE80211_M_WDS)
--		ni = ieee80211_find_txnode(vap, vap->wds_mac);
--	else
--		ni = ieee80211_find_txnode(vap, eh->ether_dhost);
-+	ni = ieee80211_find_txnode(vap, eh->ether_dhost);
- 	if (ni == NULL) {
- 		/* NB: ieee80211_find_txnode does stat+msg */
- 		goto bad;
- 	}
- 
-+	if (ni->ni_subif && (vap != ni->ni_subif) &&
-+		((eh)->ether_type != __constant_htons(ETHERTYPE_PAE)))
-+		goto bad;
-+
- 	/* calculate priority so drivers can find the TX queue */
- 	if (ieee80211_classify(ni, skb)) {
- 		IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni,
-@@ -334,20 +335,33 @@ void ieee80211_parent_queue_xmit(struct
-  * constructing a frame as it sets i_fc[1]; other bits can
-  * then be or'd in.
-  */
--static void
-+static struct ieee80211_frame *
- ieee80211_send_setup(struct ieee80211vap *vap,
- 	struct ieee80211_node *ni,
--	struct ieee80211_frame *wh,
-+	struct sk_buff *skb,
- 	int type,
- 	const u_int8_t sa[IEEE80211_ADDR_LEN],
- 	const u_int8_t da[IEEE80211_ADDR_LEN],
- 	const u_int8_t bssid[IEEE80211_ADDR_LEN])
- {
- #define	WH4(wh)	((struct ieee80211_frame_addr4 *)wh)
-+	struct ieee80211_frame *wh;
-+	int len = sizeof(struct ieee80211_frame);
-+	int opmode = vap->iv_opmode;
-+
-+	if ((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) {
-+		if ((opmode == IEEE80211_M_STA) &&
-+			(vap->iv_flags_ext & IEEE80211_FEXT_WDS))
-+			opmode = IEEE80211_M_WDS;
- 
-+		if (opmode == IEEE80211_M_WDS)
-+			len = sizeof(struct ieee80211_frame_addr4);
-+	}
-+
-+	wh = (struct ieee80211_frame *)skb_push(skb, len);
- 	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | type;
- 	if ((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) {
--		switch (vap->iv_opmode) {
-+		switch (opmode) {
- 		case IEEE80211_M_STA:
- 			wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
- 			IEEE80211_ADDR_COPY(wh->i_addr1, bssid);
-@@ -389,6 +403,8 @@ ieee80211_send_setup(struct ieee80211vap
- 	*(__le16 *)&wh->i_seq[0] =
- 	    htole16(ni->ni_txseqs[0] << IEEE80211_SEQ_SEQ_SHIFT);
- 	ni->ni_txseqs[0]++;
-+
-+	return wh;
- #undef WH4
- }
- 
-@@ -410,9 +426,7 @@ ieee80211_mgmt_output(struct ieee80211_n
- 
- 	SKB_CB(skb)->ni = ni;
- 
--	wh = (struct ieee80211_frame *)
--		skb_push(skb, sizeof(struct ieee80211_frame));
--	ieee80211_send_setup(vap, ni, wh,
-+	wh = ieee80211_send_setup(vap, ni, skb,
- 		IEEE80211_FC0_TYPE_MGT | type,
- 		vap->iv_myaddr, ni->ni_macaddr, vap->iv_bssid);
- 	/* XXX power management */
-@@ -458,6 +472,9 @@ ieee80211_send_nulldata(struct ieee80211
- 	struct ieee80211_frame *wh;
- 	u_int8_t *frm;
- 
-+	if (ni->ni_subif)
-+		vap = ni->ni_subif;
-+
- 	skb = ieee80211_getmgtframe(&frm, 0);
- 	if (skb == NULL) {
- 		/* XXX debug msg */
-@@ -466,9 +483,7 @@ ieee80211_send_nulldata(struct ieee80211
- 		return -ENOMEM;
- 	}
- 
--	wh = (struct ieee80211_frame *)
--		skb_push(skb, sizeof(struct ieee80211_frame));
--	ieee80211_send_setup(vap, ni, wh,
-+	wh = ieee80211_send_setup(vap, ni, skb,
- 		IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_NODATA,
- 		vap->iv_myaddr, ni->ni_macaddr, vap->iv_bssid);
- 	/* NB: power management bit is never sent by an AP */
-@@ -506,6 +521,7 @@ ieee80211_send_qosnulldata(struct ieee80
- 	struct sk_buff *skb;
- 	struct ieee80211_qosframe *qwh;
- 	u_int8_t *frm;
-+	u_int8_t *i_qos;
- 	int tid;
- 
- 	skb = ieee80211_getmgtframe(&frm, 2);
-@@ -517,11 +533,12 @@ ieee80211_send_qosnulldata(struct ieee80
- 	SKB_CB(skb)->ni = ieee80211_ref_node(ni);
- 
- 	skb->priority = ac;
--	qwh = (struct ieee80211_qosframe *)skb_push(skb, sizeof(struct ieee80211_qosframe));
- 
--	qwh = (struct ieee80211_qosframe *)skb->data;
-+	/* grab a pointer to QoS control and also compensate for the header length
-+	 * difference between QoS and non-QoS frame */
-+	i_qos = skb_push(skb, sizeof(struct ieee80211_qosframe) - sizeof(struct ieee80211_frame));
- 
--	ieee80211_send_setup(vap, ni, (struct ieee80211_frame *)qwh,
-+	qwh = (struct ieee80211_qosframe *) ieee80211_send_setup(vap, ni, skb,
- 		IEEE80211_FC0_TYPE_DATA,
- 		vap->iv_myaddr, /* SA */
- 		ni->ni_macaddr, /* DA */
-@@ -535,10 +552,10 @@ ieee80211_send_qosnulldata(struct ieee80
- 
- 	/* map from access class/queue to 11e header priority value */
- 	tid = WME_AC_TO_TID(ac);
--	qwh->i_qos[0] = tid & IEEE80211_QOS_TID;
-+	i_qos[0] = tid & IEEE80211_QOS_TID;
- 	if (ic->ic_wme.wme_wmeChanParams.cap_wmeParams[ac].wmep_noackPolicy)
- 		qwh->i_qos[0] |= (1 << IEEE80211_QOS_ACKPOLICY_S) & IEEE80211_QOS_ACKPOLICY;
--	qwh->i_qos[1] = 0;
-+	i_qos[1] = 0;
- 
- 	IEEE80211_NODE_STAT(ni, tx_data);
- 
-@@ -780,6 +797,8 @@ ieee80211_encap(struct ieee80211_node *n
- 		hdrsize = sizeof(struct ieee80211_frame);
- 
- 	SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE));
-+	if (ni->ni_subif)
-+		vap = ni->ni_subif;
- 
- 	switch (vap->iv_opmode) {
- 	case IEEE80211_M_IBSS:
-@@ -788,7 +807,7 @@ ieee80211_encap(struct ieee80211_node *n
- 		break;
- 	case IEEE80211_M_WDS:
- 		use4addr = 1;
--		ismulticast = IEEE80211_IS_MULTICAST(ni->ni_macaddr);
-+		ismulticast = 0;
- 		break;
- 	case IEEE80211_M_HOSTAP:
- 		if (!IEEE80211_IS_MULTICAST(eh.ether_dhost) &&
-@@ -799,20 +818,9 @@ ieee80211_encap(struct ieee80211_node *n
- 			ismulticast = IEEE80211_IS_MULTICAST(eh.ether_dhost);
- 		break;
- 	case IEEE80211_M_STA:
--		if ((vap->iv_flags_ext & IEEE80211_FEXT_WDS) &&
--		    !IEEE80211_ADDR_EQ(eh.ether_shost, vap->iv_myaddr)) {
-+		if (vap->iv_flags_ext & IEEE80211_FEXT_WDS) {
- 			use4addr = 1;
--			ismulticast = IEEE80211_IS_MULTICAST(ni->ni_macaddr);
--			/* Add a WDS entry to the station VAP */
--			if (IEEE80211_IS_MULTICAST(eh.ether_dhost)) {
--				struct ieee80211_node_table *nt = &ic->ic_sta;
--				struct ieee80211_node *ni_wds 
--					= ieee80211_find_wds_node(nt, eh.ether_shost);
--				if (ni_wds)
--					ieee80211_unref_node(&ni_wds);
--				else
--					ieee80211_add_wds_addr(nt, ni, eh.ether_shost, 0);
--			}
-+			ismulticast = 0;
- 		} else
- 			ismulticast = IEEE80211_IS_MULTICAST(vap->iv_bssid);
- 		break;
-@@ -973,7 +981,7 @@ ieee80211_encap(struct ieee80211_node *n
- 			break;
- 		case IEEE80211_M_WDS:
- 			wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS;
--			IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
-+			IEEE80211_ADDR_COPY(wh->i_addr1, vap->wds_mac);
- 			IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr);
- 			IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
- 			IEEE80211_ADDR_COPY(WH4(wh)->i_addr4, eh.ether_shost);
-@@ -1683,9 +1691,7 @@ ieee80211_send_probereq(struct ieee80211
- 
- 	SKB_CB(skb)->ni = ieee80211_ref_node(ni);
- 
--	wh = (struct ieee80211_frame *)
--		skb_push(skb, sizeof(struct ieee80211_frame));
--	ieee80211_send_setup(vap, ni, wh,
-+	wh = ieee80211_send_setup(vap, ni, skb,
- 		IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ,
- 		sa, da, bssid);
- 	/* XXX power management? */
---- a/tools/athkey.c
-+++ b/tools/athkey.c
-@@ -118,7 +118,7 @@ set80211priv(const char *dev, int op, vo
- 				IOCTL_ERR(IEEE80211_IOCTL_ADDMAC),
- 				IOCTL_ERR(IEEE80211_IOCTL_DELMAC),
- 				IOCTL_ERR(IEEE80211_IOCTL_WDSADDMAC),
--				IOCTL_ERR(IEEE80211_IOCTL_WDSDELMAC),
-+				IOCTL_ERR(IEEE80211_IOCTL_WDSSETMAC),
- 				IOCTL_ERR(IEEE80211_IOCTL_READREG),
- 				IOCTL_ERR(IEEE80211_IOCTL_WRITEREG),
- 			};
---- a/tools/athchans.c
-+++ b/tools/athchans.c
-@@ -118,7 +118,7 @@ set80211priv(const char *dev, int op, vo
- 				IOCTL_ERR(IEEE80211_IOCTL_ADDMAC),
- 				IOCTL_ERR(IEEE80211_IOCTL_DELMAC),
- 				IOCTL_ERR(IEEE80211_IOCTL_WDSADDMAC),
--				IOCTL_ERR(IEEE80211_IOCTL_WDSDELMAC),
-+				IOCTL_ERR(IEEE80211_IOCTL_WDSSETMAC),
- 				IOCTL_ERR(IEEE80211_IOCTL_READREG),
- 				IOCTL_ERR(IEEE80211_IOCTL_WRITEREG),
- 			};
---- a/tools/wlanconfig.c
-+++ b/tools/wlanconfig.c
-@@ -968,7 +968,7 @@ do80211priv(struct iwreq *iwr, const cha
- 			IOCTL_ERR(IEEE80211_IOCTL_ADDMAC),
- 			IOCTL_ERR(IEEE80211_IOCTL_DELMAC),
- 			IOCTL_ERR(IEEE80211_IOCTL_WDSADDMAC),
--			IOCTL_ERR(IEEE80211_IOCTL_WDSDELMAC),
-+			IOCTL_ERR(IEEE80211_IOCTL_WDSSETMAC),
- 			IOCTL_ERR(IEEE80211_IOCTL_READREG),
- 			IOCTL_ERR(IEEE80211_IOCTL_WRITEREG),
- 		};
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -979,6 +979,12 @@ ieee80211_init(struct net_device *dev, i
- 		"start running (state=%d)\n", vap->iv_state);
- 
- 
-+	if (vap->iv_master && vap->iv_master->iv_state == IEEE80211_S_INIT) {
-+		int ret = ieee80211_init(vap->iv_master->iv_dev, forcescan);
-+		if (ret < 0)
-+			return ret;
-+	}
-+
- 	if ((dev->flags & IFF_RUNNING) == 0) {
- 		if (ic->ic_nopened++ == 0 &&
- 		    (parent->flags & IFF_RUNNING) == 0)
-@@ -1081,6 +1087,8 @@ ieee80211_init(struct net_device *dev, i
- int
- ieee80211_open(struct net_device *dev)
- {
-+	struct ieee80211vap *vap = dev->priv;
-+
- 	return ieee80211_init(dev, 0);
- }
- 
-@@ -1090,7 +1098,7 @@ ieee80211_open(struct net_device *dev)
- void
- ieee80211_start_running(struct ieee80211com *ic)
- {
--	struct ieee80211vap *vap;
-+	struct ieee80211vap *vap, *avp;
- 	struct net_device *dev;
- 
- 	/* XXX locking */
-@@ -1099,6 +1107,16 @@ ieee80211_start_running(struct ieee80211
- 		/* NB: avoid recursion */
- 		if ((dev->flags & IFF_UP) && !(dev->flags & IFF_RUNNING))
- 			ieee80211_open(dev);
-+
-+		TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
-+			if (avp->iv_wdsnode && avp->iv_wdsnode->ni_subif == avp)
-+				continue;
-+
-+			dev = avp->iv_dev;
-+			/* NB: avoid recursion */
-+			if ((dev->flags & IFF_UP) && !(dev->flags & IFF_RUNNING))
-+				ieee80211_open(dev);
-+		}
- 	}
- }
- EXPORT_SYMBOL(ieee80211_start_running);
-@@ -1116,11 +1134,43 @@ ieee80211_stop(struct net_device *dev)
- 	struct ieee80211vap *vap = dev->priv;
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct net_device *parent = ic->ic_dev;
-+	struct ieee80211_node *tni, *ni;
-+	struct ieee80211vap *avp;
- 
- 	IEEE80211_DPRINTF(vap,
- 		IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
- 		"%s\n", "stop running");
- 
-+	if (vap->iv_wdsnode && !vap->iv_wdsnode->ni_subif)
-+		ieee80211_unref_node(&vap->iv_wdsnode);
-+
-+	/* stop wds interfaces */
-+	TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_next) {
-+		if (avp->iv_state != IEEE80211_S_INIT)
-+			ieee80211_stop(avp->iv_dev);
-+	}
-+
-+	/* get rid of all wds nodes while we're still locked */
-+	do {
-+		ni = NULL;
-+
-+		IEEE80211_NODE_TABLE_LOCK_IRQ(&ic->ic_sta);
-+		TAILQ_FOREACH(tni, &ic->ic_sta.nt_node, ni_list) {
-+			if (tni->ni_vap != vap)
-+				continue;
-+			if (!tni->ni_subif)
-+				continue;
-+			ni = tni;
-+			break;
-+		}
-+		IEEE80211_NODE_TABLE_UNLOCK_IRQ(&ic->ic_sta);
-+
-+		if (!ni)
-+			break;
-+
-+		ieee80211_node_leave(ni);
-+	} while (1);
-+
- 	ieee80211_new_state(vap, IEEE80211_S_INIT, -1);
- 	if (dev->flags & IFF_RUNNING) {
- 		dev->flags &= ~IFF_RUNNING;		/* mark us stopped */
-@@ -1148,7 +1198,7 @@ EXPORT_SYMBOL(ieee80211_stop);
- void
- ieee80211_stop_running(struct ieee80211com *ic)
- {
--	struct ieee80211vap *vap;
-+	struct ieee80211vap *vap, *avp;
- 	struct net_device *dev;
- 
- 	/* XXX locking */
-@@ -1156,6 +1206,12 @@ ieee80211_stop_running(struct ieee80211c
- 		dev = vap->iv_dev;
- 		if (dev->flags & IFF_RUNNING)	/* NB: avoid recursion */
- 			ieee80211_stop(dev);
-+
-+		TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
-+			dev = avp->iv_dev;
-+			if (dev->flags & IFF_RUNNING)	/* NB: avoid recursion */
-+				ieee80211_stop(dev);
-+		}
- 	}
- }
- EXPORT_SYMBOL(ieee80211_stop_running);
-@@ -1342,9 +1398,9 @@ ieee80211_new_state(struct ieee80211vap
- 	struct ieee80211com *ic = vap->iv_ic;
- 	int rc;
- 
--	IEEE80211_VAPS_LOCK_BH(ic);
-+	IEEE80211_VAPS_LOCK_IRQ(ic);
- 	rc = vap->iv_newstate(vap, nstate, arg);
--	IEEE80211_VAPS_UNLOCK_BH(ic);
-+	IEEE80211_VAPS_UNLOCK_IRQ(ic);
- 	return rc;
- }
- 
-@@ -1557,57 +1613,12 @@ __ieee80211_newstate(struct ieee80211vap
- 		switch (ostate) {
- 		case IEEE80211_S_INIT:
- 			if (vap->iv_opmode == IEEE80211_M_MONITOR ||
--			    vap->iv_opmode == IEEE80211_M_WDS ||
- 			    vap->iv_opmode == IEEE80211_M_HOSTAP) {
- 				/*
- 				 * Already have a channel; bypass the
- 				 * scan and startup immediately.
- 				 */
- 				ieee80211_create_ibss(vap, ic->ic_curchan);
--
--				/* In WDS mode, allocate and initialize peer node. */
--				if (vap->iv_opmode == IEEE80211_M_WDS) {
--					/* XXX: This is horribly non-atomic. */
--					struct ieee80211_node *wds_ni =
--						ieee80211_find_node(&ic->ic_sta,
--								vap->wds_mac);
--
--					if (wds_ni == NULL) {
--						wds_ni = ieee80211_alloc_node_table(
--								vap,
--								vap->wds_mac);
--						if (wds_ni != NULL) {
--							ieee80211_add_wds_addr(
--									&ic->ic_sta,
--									wds_ni,
--									vap->wds_mac,
--									1);
--							ieee80211_ref_node(wds_ni); /* pin in memory */
--						}
--						else
--							IEEE80211_DPRINTF(
--									vap,
--									IEEE80211_MSG_NODE,
--									"%s: Unable to "
--									"allocate node for "
--									"WDS: " MAC_FMT "\n",
--									__func__,
--									MAC_ADDR(
--										vap->wds_mac)
--									);
--					}
--
--					if (wds_ni != NULL) {
--						ieee80211_node_authorize(wds_ni);
--						wds_ni->ni_chan =
--							vap->iv_bss->ni_chan;
--						wds_ni->ni_capinfo =
--							ni->ni_capinfo;
--						wds_ni->ni_associd = 1;
--						wds_ni->ni_ath_flags =
--							vap->iv_ath_cap;
--					}
--				}
- 				break;
- 			}
- 			/* fall thru... */
-@@ -1675,6 +1686,7 @@ __ieee80211_newstate(struct ieee80211vap
- 		 */
- 		if (ni->ni_authmode != IEEE80211_AUTH_8021X)
- 			ieee80211_node_authorize(ni);
-+
- #ifdef ATH_SUPERG_XR
- 		/*
- 		 * fire a timer to bring up XR vap if configured.
-@@ -1808,6 +1820,11 @@ ieee80211_newstate(struct ieee80211vap *
- 			  ieee80211_state_name[dstate]);
- 
- 	ieee80211_update_link_status(vap, nstate, ostate);
-+
-+	if ((nstate != IEEE80211_S_RUN) && vap->iv_wdsnode &&
-+			!vap->iv_wdsnode->ni_subif)
-+		ieee80211_unref_node(&vap->iv_wdsnode);
-+
- 	switch (nstate) {
- 	case IEEE80211_S_AUTH:
- 	case IEEE80211_S_ASSOC:
-@@ -1930,8 +1947,15 @@ ieee80211_newstate(struct ieee80211vap *
- 		if (ostate == IEEE80211_S_SCAN || 
- 		    ostate == IEEE80211_S_AUTH ||
- 		    ostate == IEEE80211_S_ASSOC) {
-+
- 			/* Transition (S_SCAN|S_AUTH|S_ASSOC) -> S_RUN */
- 			__ieee80211_newstate(vap, nstate, arg);
-+
-+			/* if we're in wds, let the ap know that we're doing this */
-+			if ((vap->iv_opmode == IEEE80211_M_STA) &&
-+				(vap->iv_flags_ext & IEEE80211_FEXT_WDS))
-+					ieee80211_send_nulldata(ieee80211_ref_node(vap->iv_bss));
-+
- 			/* Then bring up all other vaps pending on the scan */
- 			dstate = get_dominant_state(ic);
- 			if (dstate == IEEE80211_S_RUN) {
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -79,28 +79,6 @@ typedef void *TQUEUE_ARG;
- #define	tasklet_enable(t)	do { (void) t; local_bh_enable(); } while (0)
- #endif /* !DECLARE_TASKLET */
- 
--#include <linux/sched.h>
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41)
--#include <linux/tqueue.h>
--#define work_struct			tq_struct
--#define schedule_work(t)		schedule_task((t))
--#define flush_scheduled_work()		flush_scheduled_tasks()
--#define ATH_INIT_WORK(t, f) do { 			\
--	memset((t), 0, sizeof(struct tq_struct)); \
--	(t)->routine = (void (*)(void*)) (f); 	\
--	(t)->data=(void *) (t);			\
--} while (0)
--#else
--#include <linux/workqueue.h>
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
--#define ATH_INIT_WORK(_t, _f)	INIT_WORK((_t), (void (*)(void *))(_f), (_t));
--#else
--#define ATH_INIT_WORK(_t, _f)	INIT_WORK((_t), (_f));
--#endif
--
--#endif /* KERNEL_VERSION < 2.5.41 */
--
- /*
-  * Guess how the interrupt handler should work.
-  */
---- a/net80211/ieee80211_linux.c
-+++ b/net80211/ieee80211_linux.c
-@@ -145,7 +145,7 @@ ieee80211_getmgtframe(u_int8_t **frm, u_
- 	struct sk_buff *skb;
- 	u_int len;
- 
--	len = roundup(sizeof(struct ieee80211_frame) + pktlen, 4);
-+	len = roundup(sizeof(struct ieee80211_frame_addr4) + pktlen, 4);
- #ifdef IEEE80211_DEBUG_REFCNT
- 	skb = ieee80211_dev_alloc_skb_debug(len + align - 1, func, line);
- #else
-@@ -161,7 +161,7 @@ ieee80211_getmgtframe(u_int8_t **frm, u_
- 		SKB_CB(skb)->flags = 0;
- 		SKB_CB(skb)->next = NULL;
- 
--		skb_reserve(skb, sizeof(struct ieee80211_frame));
-+		skb_reserve(skb, sizeof(struct ieee80211_frame_addr4));
- 		*frm = skb_put(skb, pktlen);
- 	}
- 	return skb;
---- a/net80211/ieee80211_node.h
-+++ b/net80211/ieee80211_node.h
-@@ -92,11 +92,13 @@ struct ath_softc;
-  * the ieee80211com structure.
-  */
- struct ieee80211_node {
--	struct ieee80211vap *ni_vap;
-+	struct ieee80211vap *ni_vap, *ni_subif;
- 	struct ieee80211com *ni_ic;
- 	struct ieee80211_node_table *ni_table;
- 	TAILQ_ENTRY(ieee80211_node) ni_list;
- 	LIST_ENTRY(ieee80211_node) ni_hash;
-+	struct work_struct ni_create;	/* task for creating a subif */
-+	struct work_struct ni_destroy;	/* task for destroying a subif */
- 	atomic_t ni_refcnt;
- 	u_int ni_scangen;			/* gen# for timeout scan */
- 	u_int8_t ni_authmode;			/* authentication algorithm */
-@@ -430,5 +432,6 @@ void ieee80211_node_join(struct ieee8021
- void ieee80211_node_leave(struct ieee80211_node *);
- u_int8_t ieee80211_getrssi(struct ieee80211com *);
- int32_t ieee80211_get_node_count(struct ieee80211com *);
-+void ieee80211_wds_addif(struct ieee80211_node *ni);
- #endif /* _NET80211_IEEE80211_NODE_H_ */
- 
diff --git a/package/madwifi/patches/372-queue_vif.patch b/package/madwifi/patches/372-queue_vif.patch
deleted file mode 100644
index 8b13abc33c..0000000000
--- a/package/madwifi/patches/372-queue_vif.patch
+++ /dev/null
@@ -1,39 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -1198,6 +1198,7 @@ ieee80211_deliver_data(struct ieee80211_
- 		}
- 		if (skb1 != NULL) {
- 			struct ieee80211_node *ni_tmp;
-+			int ret;
- 			skb1->dev = dev;
- 			skb_reset_mac_header(skb1);
- 			skb_set_network_header(skb1, sizeof(struct ether_header));
-@@ -1205,7 +1206,12 @@ ieee80211_deliver_data(struct ieee80211_
- 			skb1->protocol = __constant_htons(ETH_P_802_2);
- 			/* XXX insert vlan tag before queue it? */
- 			ni_tmp = SKB_CB(skb1)->ni; /* remember node so we can free it */
--			if (dev_queue_xmit(skb1) == NET_XMIT_DROP) {
-+			ret = dev->hard_start_xmit(skb1, dev);
-+
-+			if (ret == NETDEV_TX_BUSY)
-+				ieee80211_dev_kfree_skb(&skb1);
-+
-+			else if (ret != NETDEV_TX_OK) {
- 				/* If queue dropped the packet because device was
- 				 * too busy */
- 				vap->iv_devstats.tx_dropped++;
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -324,9 +324,10 @@ void ieee80211_parent_queue_xmit(struct
- 	/* Dispatch the packet to the parent device */
- 	skb->dev = vap->iv_ic->ic_dev;
- 
--	if (dev_queue_xmit(skb) == NET_XMIT_DROP)
-+	if (netif_queue_stopped(skb->dev))
-+		ieee80211_dev_kfree_skb(&skb);
-+	else if (dev_queue_xmit(skb) == NET_XMIT_DROP)
- 		vap->iv_devstats.tx_dropped++;
--
- }
- 
- /*
diff --git a/package/madwifi/patches/373-sanity_check.patch b/package/madwifi/patches/373-sanity_check.patch
deleted file mode 100644
index 06c6acf08e..0000000000
--- a/package/madwifi/patches/373-sanity_check.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -250,6 +250,9 @@ ieee80211_input(struct ieee80211vap * va
- 	if (vap->iv_opmode == IEEE80211_M_MONITOR)
- 		goto out;
- 
-+	if (!skb->data)
-+		goto out;
-+
- 	if (skb->len < sizeof(struct ieee80211_frame_min)) {
- 		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
- 			ni->ni_macaddr, NULL,
diff --git a/package/madwifi/patches/374-nbtt_fix.patch b/package/madwifi/patches/374-nbtt_fix.patch
deleted file mode 100644
index 38a1c59d55..0000000000
--- a/package/madwifi/patches/374-nbtt_fix.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -5486,6 +5486,9 @@ ath_beacon_config(struct ath_softc *sc,
- 		ath_beacon_dturbo_config(vap, intval &
- 				~(HAL_BEACON_RESET_TSF | HAL_BEACON_ENA));
- #endif
-+		if ((nexttbtt & HAL_BEACON_PERIOD) - (ath_hal_gettsf32(ah) >> 10)
-+				<= ath_hal_sw_beacon_response_time)
-+			nexttbtt += intval;
- 		sc->sc_nexttbtt = nexttbtt;
- 		ath_hal_beaconinit(ah, nexttbtt, intval);
- 		if (intval & HAL_BEACON_RESET_TSF) {
---- a/ath_hal/ah_os.c
-+++ b/ath_hal/ah_os.c
-@@ -71,6 +71,7 @@ static	int ath_hal_debug = 99;
- int	ath_hal_dma_beacon_response_time = 2;	/* in TUs */
- int	ath_hal_sw_beacon_response_time = 10;	/* in TUs */
- int	ath_hal_additional_swba_backoff = 0;	/* in TUs */
-+EXPORT_SYMBOL(ath_hal_sw_beacon_response_time);
- 
- struct ath_hal *
- _ath_hal_attach(u_int16_t devid, HAL_SOFTC sc,
diff --git a/package/madwifi/patches/375-atim_tsf_update.patch b/package/madwifi/patches/375-atim_tsf_update.patch
deleted file mode 100644
index d1313aa564..0000000000
--- a/package/madwifi/patches/375-atim_tsf_update.patch
+++ /dev/null
@@ -1,141 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -161,6 +161,7 @@ static void ath_beacon_send(struct ath_s
- static void ath_beacon_return(struct ath_softc *, struct ath_buf *);
- static void ath_beacon_free(struct ath_softc *);
- static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *);
-+static void ath_hw_beacon_stop(struct ath_softc *sc);
- static int ath_desc_alloc(struct ath_softc *);
- static void ath_desc_free(struct ath_softc *);
- static void ath_desc_swap(struct ath_desc *);
-@@ -2793,6 +2794,72 @@ ath_set_ack_bitrate(struct ath_softc *sc
- 	return 1;
- }
- 
-+static void
-+ath_hw_beacon_stop(struct ath_softc *sc)
-+{
-+	HAL_BEACON_TIMERS btimers;
-+
-+	btimers.bt_intval = 0;
-+	btimers.bt_nexttbtt = 0;
-+	btimers.bt_nextdba = 0xffffffff;
-+	btimers.bt_nextswba = 0xffffffff;
-+	btimers.bt_nextatim = 0;
-+
-+	ath_hal_setbeacontimers(sc->sc_ah, &btimers);
-+}
-+
-+/* Fix up the ATIM window after TSF resync */
-+static int
-+ath_hw_check_atim(struct ath_softc *sc, int window, int intval)
-+{
-+#define AR5K_TIMER0_5210       0x802c  /* Next beacon time register */
-+#define AR5K_TIMER0_5211       0x8028
-+#define AR5K_TIMER3_5210       0x8038  /* End of ATIM window time register */
-+#define AR5K_TIMER3_5211       0x8034
-+	struct ath_hal *ah = sc->sc_ah;
-+	int dev = sc->sc_ah->ah_macType;
-+	unsigned int nbtt, atim;
-+	int is_5210 = 0;
-+
-+	/*
-+	 * check if the ATIM window is still correct:
-+	 *   1.) usually ATIM should be NBTT + window
-+	 *   2.) nbtt already updated
-+	 *   3.) nbtt already updated and has wrapped around
-+	 *   4.) atim has wrapped around
-+	 */
-+	switch(dev) {
-+	case 5210:
-+		nbtt = OS_REG_READ(ah, AR5K_TIMER0_5210);
-+		atim = OS_REG_READ(ah, AR5K_TIMER3_5210);
-+		is_5210 = 1;
-+		break;
-+	case 5211:
-+	case 5212:
-+		nbtt = OS_REG_READ(ah, AR5K_TIMER0_5211);
-+		atim = OS_REG_READ(ah, AR5K_TIMER3_5211);
-+		break;
-+	/* NB: 5416+ doesn't do ATIM in hw */
-+	case 5416:
-+	default:
-+		return 0;
-+	}
-+
-+	if ((atim - nbtt != window) &&				/* 1.) */
-+	    (nbtt - atim != intval - window) &&			/* 2.) */
-+	    ((nbtt | 0x10000) - atim != intval - window) &&	/* 3.) */
-+	    ((atim | 0x10000) - nbtt != window)) {		/* 4.) */
-+		if (is_5210)
-+			OS_REG_WRITE(ah, AR5K_TIMER3_5210, nbtt + window );
-+		else
-+			OS_REG_WRITE(ah, AR5K_TIMER3_5211, nbtt + window );
-+		return atim - nbtt;
-+	}
-+
-+	return 0;
-+}
-+
-+
- /*
-  * Reset the hardware w/o losing operational state.  This is
-  * basically a more efficient way of doing ath_stop, ath_init,
-@@ -5294,6 +5361,7 @@ ath_beacon_config(struct ath_softc *sc,
- 	u_int64_t tsf, hw_tsf;
- 	u_int32_t tsftu, hw_tsftu;
- 	u_int32_t intval, nexttbtt = 0;
-+	unsigned long flags;
- 	int reset_tsf = 0;
- 
- 	if (vap == NULL)
-@@ -5301,6 +5369,9 @@ ath_beacon_config(struct ath_softc *sc,
- 
- 	ni = vap->iv_bss;
- 
-+	/* TSF calculation is timing critical - we don't want to be interrupted here */
-+	local_irq_save(flags);
-+
- 	hw_tsf = ath_hal_gettsf64(ah);
- 	tsf = le64_to_cpu(ni->ni_tstamp.tsf);
- 	hw_tsftu = hw_tsf >> 10;
-@@ -5490,15 +5561,27 @@ ath_beacon_config(struct ath_softc *sc,
- 				<= ath_hal_sw_beacon_response_time)
- 			nexttbtt += intval;
- 		sc->sc_nexttbtt = nexttbtt;
-+
-+		/* stop beacons before reconfiguring the timers to avoid race
-+		 * conditions. ath_hal_beaconinit will start them again */
-+		ath_hw_beacon_stop(sc);
-+
- 		ath_hal_beaconinit(ah, nexttbtt, intval);
- 		if (intval & HAL_BEACON_RESET_TSF) {
- 			sc->sc_last_tsf = 0;
- 		}
- 		sc->sc_bmisscount = 0;
- 		ath_hal_intrset(ah, sc->sc_imask);
-+
-+		if ((sc->sc_opmode == HAL_M_IBSS) && ath_hw_check_atim(sc, 1, intval & HAL_BEACON_PERIOD)) {
-+			DPRINTF(sc, ATH_DEBUG_BEACON,
-+				"fixed atim window after beacon init\n");
-+		}
- 	}
- 
- ath_beacon_config_debug:
-+	local_irq_restore(flags);
-+
- 	/* We print all debug messages here, in order to preserve the
- 	 * time critical aspect of this function */
- 	DPRINTF(sc, ATH_DEBUG_BEACON,
-@@ -6401,6 +6484,11 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 			DPRINTF(sc, ATH_DEBUG_BEACON, 
- 				"Updated beacon timers\n");
- 		}
-+		if ((sc->sc_opmode == HAL_M_IBSS) &&
-+				IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid) &&
-+				ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval)) {
-+			DPRINTF(sc, ATH_DEBUG_ANY, "Fixed ATIM window after beacon recv\n");
-+		}
- 		/* NB: Fall Through */
- 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
- 		if (vap->iv_opmode == IEEE80211_M_IBSS &&
diff --git a/package/madwifi/patches/377-disable_vlan_code.patch b/package/madwifi/patches/377-disable_vlan_code.patch
deleted file mode 100644
index 8a132484e6..0000000000
--- a/package/madwifi/patches/377-disable_vlan_code.patch
+++ /dev/null
@@ -1,25 +0,0 @@
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -657,22 +657,7 @@ int ieee80211_proc_vcreate(struct ieee80
- 	       char *);
- void ieee80211_proc_cleanup(struct ieee80211vap *);
- 
--#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
--#define IEEE80211_VLAN_TAG_USED 1
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20)
--#define	vlan_hwaccel_receive_skb(skb, grp, tag)	vlan_hwaccel_rx(skb, grp, tag)
--#endif
--
--#ifndef VLAN_GROUP_ARRAY_PART_LEN
--#define vlan_group_set_device(group, vid, dev) do { \
--	group->vlan_devices[vid] = dev; \
--} while (0);
--#endif
--
--#else
- #define IEEE80211_VLAN_TAG_USED 0
--#endif
- void ieee80211_vlan_vattach(struct ieee80211vap *);
- void ieee80211_vlan_vdetach(struct ieee80211vap *);
- 
diff --git a/package/madwifi/patches/378-adhoc_crash_fix.patch b/package/madwifi/patches/378-adhoc_crash_fix.patch
deleted file mode 100644
index 5b91683674..0000000000
--- a/package/madwifi/patches/378-adhoc_crash_fix.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -3529,6 +3529,11 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 		if (ic->ic_flags & IEEE80211_F_SCAN) {
- 			ieee80211_add_scan(vap, &scan, wh, subtype, rssi, rtsf);
- 		}
-+
-+		/* stop processing if the bss channel is not set up yet */
-+		if (!ic->ic_bsschan || ic->ic_bsschan == IEEE80211_CHAN_ANYC)
-+			break;
-+
- 		/* NB: Behavior of WDS-Link and Ad-Hoc is very similar here:
- 		 * When we receive a beacon that belongs to the AP that we're
- 		 * connected to, use it to refresh the local node info.
diff --git a/package/madwifi/patches/379-invalid_rate_fix.patch b/package/madwifi/patches/379-invalid_rate_fix.patch
deleted file mode 100644
index c96c04daff..0000000000
--- a/package/madwifi/patches/379-invalid_rate_fix.patch
+++ /dev/null
@@ -1,405 +0,0 @@
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -111,27 +111,13 @@
- #include <net80211/ieee80211_var.h>
- #include <net80211/ieee80211_rate.h>
- 
-+#include "if_ath_debug.h"
- #include "if_athvar.h"
- #include "if_ath_hal.h"
- #include "ah_desc.h"
- 
- #include "minstrel.h"
- 
--#ifdef AR_DEBUG
--#define	MINSTREL_DEBUG
--#endif
--#ifdef MINSTREL_DEBUG
--enum {
--		ATH_DEBUG_RATE		= 0x00000010	/* rate control */
--};
--#define	DPRINTF(sc, _fmt, ...) do {		\
--		if (sc->sc_debug & ATH_DEBUG_RATE)	\
--			printk(_fmt, __VA_ARGS__);		\
--} while (0)
--#else
--#define	DPRINTF(sc, _fmt, ...)
--#endif
--
- #define ONE_SECOND (1000 * 1000)  /* 1 second, or 1000 milliseconds; eternity, in other words */
- 
- #include "release.h"
-@@ -471,11 +457,11 @@ ath_rate_tx_complete(struct ath_softc *s
- 		final_rate = sc->sc_hwmap[ts->ts_rate & ~HAL_TXSTAT_ALTRATE].ieeerate;
- 		final_ndx = rate_to_ndx(sn, final_rate);
- 		if (final_ndx >= sn->num_rates) {
--			DPRINTF(sc, "%s: final ndx too high\n", __func__);
-+			DPRINTF(sc, ATH_DEBUG_RATE, "%s: final ndx too high\n", __func__);
- 			final_ndx = 0;
- 		}
- 		if (final_ndx < 0) {
--			DPRINTF(sc, "%s: final ndx too low\n", __func__);
-+			DPRINTF(sc, ATH_DEBUG_RATE, "%s: final ndx too low\n", __func__);
- 			final_ndx = 0;
- 		}
- 
-@@ -485,7 +471,7 @@ ath_rate_tx_complete(struct ath_softc *s
- 		tries = ts->ts_longretry + 1;
- 
- 		if (sn->num_rates <= 0) {
--			DPRINTF(sc, "%s: " MAC_FMT " %s no rates yet\n", dev_info,
-+			DPRINTF(sc, ATH_DEBUG_RATE, "%s: " MAC_FMT " %s no rates yet\n", dev_info,
- 				MAC_ADDR(an->an_node.ni_macaddr), __func__);
- 			return;
- 		}
-@@ -551,7 +537,7 @@ ath_rate_tx_complete(struct ath_softc *s
- static void
- ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
- {
--		DPRINTF(sc, "%s: " MAC_FMT " %s\n", dev_info,
-+		DPRINTF(sc, ATH_DEBUG_RATE, "%s: " MAC_FMT " %s\n", dev_info,
- 			MAC_ADDR(an->an_node.ni_macaddr), __func__);
- 		if (isnew)
- 			ath_rate_ctl_reset(sc, &an->an_node);
-@@ -601,7 +587,7 @@ ath_fill_sample_table(struct minstrel_no
- 			    p = rates + sprintf(rates, "rates :: %d ", column_index);
- 			    for (i = 0; i < num_sample_rates; i++)
- 			            p += sprintf(p, "%2u ", sn->rs_sampleTable[i][column_index]);
--			    DPRINTF(sc, "%s\n", rates);
-+			    DPRINTF(sc, ATH_DEBUG_RATE, "%s\n", rates);
- 		};
- #endif
- }
-@@ -628,7 +614,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 		sn->is_sampling = 0;
- 
- 		if (rt == NULL) {
--			DPRINTF(sc, "no rates yet! mode %u\n", sc->sc_curmode);
-+			DPRINTF(sc, ATH_DEBUG_RATE, "no rates yet! mode %u\n", sc->sc_curmode);
- 			return;
- 		}
- 		sn->static_rate_ndx = -1;
-@@ -658,7 +644,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 			sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
- 			}
- 			if (sn->rates[x].rix == 0xff) {
--				DPRINTF(sc, "%s: %s ignore bogus rix at %d\n",
-+				DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s ignore bogus rix at %d\n",
- 					dev_info, __func__, x);
- 				continue;
- 			}
-@@ -673,7 +659,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 		ni->ni_txrate = 0;
- 
- 		if (sn->num_rates <= 0) {
--			DPRINTF(sc, "%s: %s " MAC_FMT " no rates (fixed %d) \n",
-+			DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s " MAC_FMT " no rates (fixed %d) \n",
- 				dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
- 				vap->iv_fixed_rate);
- 			/* There are no rates yet; we're done */
-@@ -689,23 +675,23 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 			 * the node.  We know the rate is there because the
- 			 * rate set is checked when the station associates. */
- 			/* NB: the rate set is assumed sorted */
--			for (; (srate >= 0) && (ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate; srate--);
--
--			KASSERT(srate >= 0,
--				("fixed rate %d not in rate set", vap->iv_fixed_rate));
-+			for (; (srate > 0) && (ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate; srate--);
- 
- 			sn->static_rate_ndx = srate;
- 			ni->ni_txrate = srate;
--			DPRINTF(sc, "%s: %s " MAC_FMT " fixed rate %d%sMbps\n",
--				dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
--				sn->rates[srate].rate / 2,
--				(sn->rates[srate].rate % 2) ? ".5 " : " ");
-+			if ((ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate)
-+				EPRINTF(sc, "Invalid static rate, falling back to basic rate\n");
-+			else
-+				DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s " MAC_FMT " fixed rate %d%sMbps\n",
-+					dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
-+					sn->rates[srate].rate / 2,
-+					(sn->rates[srate].rate % 2) ? ".5 " : " ");
- 			return;
- 		}
- 
- 		for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
- 			if (sn->rates[x].rix == 0xff) {
--				DPRINTF(sc, "%s: %s ignore bogus rix at %d\n",
-+				DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s ignore bogus rix at %d\n",
- 					dev_info, __func__, x);
- 				continue;
- 			}
-@@ -735,9 +721,9 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 		}
- 
- #if 0
--		DPRINTF(sc, "%s: Retry table for this node\n", __func__);
-+		DPRINTF(sc, ATH_DEBUG_RATE, "%s: Retry table for this node\n", __func__);
- 		  for (x = 0; x < ni->ni_rates.rs_nrates; x++)
--			     DPRINTF(sc, "%2d  %2d %6d  \n", x, sn->retry_count[x], sn->perfect_tx_time[x]);
-+			     DPRINTF(sc, ATH_DEBUG_RATE, "%2d  %2d %6d  \n", x, sn->retry_count[x], sn->perfect_tx_time[x]);
- #endif
- 
- 		/* Set the initial rate */
-@@ -781,10 +767,10 @@ ath_timer_function(unsigned long data)
- 		unsigned int interval = ath_timer_interval;
- 
- 		if (dev == NULL)
--			DPRINTF(sc, "%s: 'dev' is null in this timer \n", __func__);
-+			DPRINTF(sc, ATH_DEBUG_RATE, "%s: 'dev' is null in this timer \n", __func__);
- 
- 		if (sc == NULL)
--			DPRINTF(sc, "%s: 'sc' is null in this timer\n", __func__);
-+			DPRINTF(sc, ATH_DEBUG_RATE, "%s: 'sc' is null in this timer\n", __func__);
- 
- 		ic = &sc->sc_ic;
- 
-@@ -808,7 +794,7 @@ ath_timer_function(unsigned long data)
- 
- 		timer  = &(ssc->timer);
- 		if (timer == NULL)
--			DPRINTF(sc, "%s: timer is null - leave it\n", __func__);
-+			DPRINTF(sc, ATH_DEBUG_RATE, "%s: timer is null - leave it\n", __func__);
- 
- 		timer->expires = jiffies + ((HZ * interval) / 1000);
- 		add_timer(timer);
-@@ -904,7 +890,7 @@ static struct ath_ratectrl *
- ath_rate_attach(struct ath_softc *sc)
- {
- 		struct minstrel_softc *osc;
--		DPRINTF(sc, "%s: %s\n", dev_info, __func__);
-+		DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s\n", dev_info, __func__);
- 
- 		_MOD_INC_USE(THIS_MODULE, return NULL);
- 		osc = kmalloc(sizeof(struct minstrel_softc), GFP_ATOMIC);
-@@ -963,7 +949,7 @@ ath_proc_read_nodes(struct ieee80211vap
- 					p += sprintf(p, "out of room for node " MAC_FMT "\n\n", MAC_ADDR(ni->ni_macaddr));
- 					break;
- 				}
--				DPRINTF(sc, "%s: out of memeory to write tall of the nodes\n", __func__);
-+				DPRINTF(sc, ATH_DEBUG_RATE, "%s: out of memeory to write tall of the nodes\n", __func__);
- 			            break;
- 			}
- 			an = ATH_NODE(ni);
---- a/ath_rate/amrr/amrr.c
-+++ b/ath_rate/amrr/amrr.c
-@@ -64,24 +64,13 @@
- #include <net80211/ieee80211_var.h>
- #include <net80211/ieee80211_rate.h>
- 
-+#include "if_ath_debug.h"
- #include "if_athvar.h"
- #include "if_ath_hal.h"
- #include "ah_desc.h"
- 
- #include "amrr.h"
- 
--#ifdef AR_DEBUG
--#define	AMRR_DEBUG
--#endif
--#ifdef AMRR_DEBUG
--#define	DPRINTF(sc, _fmt, ...) do {					\
--	if (sc->sc_debug & 0x10)					\
--		printk(_fmt, __VA_ARGS__);				\
--} while (0)
--#else
--#define	DPRINTF(sc, _fmt, ...)
--#endif
--
- static int ath_rateinterval = 1000;		/* rate ctl interval (ms)  */
- static int ath_rate_max_success_threshold = 10;
- static int ath_rate_min_success_threshold = 1;
-@@ -197,7 +186,7 @@ ath_rate_update(struct ath_softc *sc, st
- 
- 	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
- 
--	DPRINTF(sc, "%s: set xmit rate for " MAC_FMT " to %dM\n",
-+	DPRINTF(sc, ATH_DEBUG_RATE, "%s: set xmit rate for " MAC_FMT " to %dM\n",
- 		__func__, MAC_ADDR(ni->ni_macaddr),
- 		ni->ni_rates.rs_nrates > 0 ?
- 			(ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0);
-@@ -297,9 +286,9 @@ ath_rate_ctl_start(struct ath_softc *sc,
- 		 * rate set is checked when the station associates.
- 		 */
- 		srate = ni->ni_rates.rs_nrates - 1;
--		for (; srate >= 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
--		KASSERT(srate >= 0,
--			("fixed rate %d not in rate set", vap->iv_fixed_rate));
-+		for (; srate > 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
-+		if (RATE(srate) != vap->iv_fixed_rate)
-+			EPRINTF(sc, "Invalid static rate, falling back to basic rate\n");
- 	}
- 	ath_rate_update(sc, ni, srate);
- #undef RATE
-@@ -377,7 +366,7 @@ ath_rate_ctl(void *arg, struct ieee80211
- 
- 	old_rate = ni->ni_txrate;
- 
--  	DPRINTF (sc, "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d\n",
-+  	DPRINTF(sc, ATH_DEBUG_RATE, "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d\n",
- 		 amn->amn_tx_try0_cnt,
- 		 amn->amn_tx_try1_cnt,
- 		 amn->amn_tx_try2_cnt,
-@@ -390,7 +379,7 @@ ath_rate_ctl(void *arg, struct ieee80211
-   			amn->amn_recovery = 1;
-   			amn->amn_success = 0;
-   			ni->ni_txrate++;
--			DPRINTF(sc, "increase rate to %d\n", ni->ni_txrate);
-+			DPRINTF(sc, ATH_DEBUG_RATE, "increase rate to %d\n", ni->ni_txrate);
-   		} else
- 			amn->amn_recovery = 0;
-   	} else if (is_failure(amn)) {
-@@ -401,12 +390,12 @@ ath_rate_ctl(void *arg, struct ieee80211
-   				amn->amn_success_threshold *= 2;
-   				amn->amn_success_threshold = min(amn->amn_success_threshold,
- 								  (u_int)ath_rate_max_success_threshold);
-- 				DPRINTF(sc, "decrease rate recovery thr: %d\n",
-+ 				DPRINTF(sc, ATH_DEBUG_RATE, "decrease rate recovery thr: %d\n",
- 					amn->amn_success_threshold);
-   			} else {
-   				/* simple failure. */
-  				amn->amn_success_threshold = ath_rate_min_success_threshold;
-- 				DPRINTF(sc, "decrease rate normal thr: %d\n",
-+ 				DPRINTF(sc, ATH_DEBUG_RATE, "decrease rate normal thr: %d\n",
- 					amn->amn_success_threshold);
-   			}
- 			amn->amn_recovery = 0;
---- a/ath_rate/onoe/onoe.c
-+++ b/ath_rate/onoe/onoe.c
-@@ -60,27 +60,13 @@
- #include <net80211/ieee80211_var.h>
- #include <net80211/ieee80211_rate.h>
- 
-+#include "if_ath_debug.h"
- #include "if_athvar.h"
- #include "if_ath_hal.h"
- #include "ah_desc.h"
- 
- #include "onoe.h"
- 
--#ifdef AR_DEBUG
--#define	ONOE_DEBUG
--#endif
--#ifdef ONOE_DEBUG
--enum {
--	ATH_DEBUG_RATE	= 0x00000010,	/* rate control */
--};
--#define	DPRINTF(sc, _fmt, ...) do {				\
--	if (sc->sc_debug & ATH_DEBUG_RATE)			\
--		printk(_fmt, __VA_ARGS__);			\
--} while (0)
--#else
--#define	DPRINTF(sc, _fmt, ...)
--#endif
--
- /*
-  * Default parameters for the rate control algorithm.  These are
-  * all tunable with sysctls.  The rate controller runs periodically
-@@ -186,7 +172,7 @@ ath_rate_update(struct ath_softc *sc, st
- 
- 	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
- 
--	DPRINTF(sc, "%s: set xmit rate for " MAC_FMT " to %dM\n",
-+	DPRINTF(sc, ATH_DEBUG_RATE, "%s: set xmit rate for " MAC_FMT " to %dM\n",
- 		__func__, MAC_ADDR(ni->ni_macaddr),
- 		ni->ni_rates.rs_nrates > 0 ?
- 			(ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0);
-@@ -283,9 +269,9 @@ ath_rate_ctl_start(struct ath_softc *sc,
- 		 */
- 		/* NB: the rate set is assumed sorted */
- 		srate = ni->ni_rates.rs_nrates - 1;
--		for (; srate >= 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
--		KASSERT(srate >= 0,
--			("fixed rate %d not in rate set", vap->iv_fixed_rate));
-+		for (; srate > 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
-+		if (RATE(srate) != vap->iv_fixed_rate)
-+			EPRINTF(sc, "Invalid static rate, falling back to basic rate\n");
- 	}
- 	ath_rate_update(sc, ni, srate);
- #undef RATE
-@@ -364,7 +350,7 @@ ath_rate_ctl(void *arg, struct ieee80211
- 	    on->on_tx_retr < (on->on_tx_ok * ath_rate_raise) / 100)
- 		dir = 1;
- 
--	DPRINTF(sc, MAC_FMT ": ok %d err %d retr %d upper %d dir %d\n",
-+	DPRINTF(sc, ATH_DEBUG_RATE, MAC_FMT ": ok %d err %d retr %d upper %d dir %d\n",
- 		MAC_ADDR(ni->ni_macaddr),
- 		on->on_tx_ok, on->on_tx_err, on->on_tx_retr,
- 		on->on_tx_upper, dir);
-@@ -395,7 +381,7 @@ ath_rate_ctl(void *arg, struct ieee80211
- 	}
- 
- 	if (nrate != ni->ni_txrate) {
--		DPRINTF(sc, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n",
-+		DPRINTF(sc, ATH_DEBUG_RATE, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n",
- 		    __func__,
- 		    (rs->rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL) / 2,
- 		    (rs->rs_rates[nrate] & IEEE80211_RATE_VAL) / 2,
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -62,30 +62,13 @@
- #include <net80211/ieee80211_var.h>
- #include <net80211/ieee80211_rate.h>
- 
-+#include "if_ath_debug.h"
- #include "if_athvar.h"
- #include "if_ath_hal.h"
- #include "ah_desc.h"
- 
- #include "sample.h"
- 
--#ifdef AR_DEBUG
--#define SAMPLE_DEBUG
--#endif
--#ifdef SAMPLE_DEBUG
--enum {
--	ATH_DEBUG_RATE		= 0x00000010,	/* rate control */
--	ATH_DEBUG_ANY		= 0xffffffff
--};
--#define	DPRINTF(sc, m, fmt, ...) do {				\
--	if (sc->sc_debug & (m))					\
--		printk(fmt, __VA_ARGS__);			\
--} while (0)
--#else
--#define	DPRINTF(sc, m, fmt, ...) do {				\
--	(void) sc;						\
--} while (0)
--#endif
--
- /*
-  * This file is an implementation of the SampleRate algorithm
-  * in "Bit-rate Selection in Wireless Networks"
-@@ -740,7 +723,7 @@ ath_rate_tx_complete(struct ath_softc *s
- 		ndx[3] = rate_to_ndx(sn, rate[3]);
- 
- #if 0
--		DPRINTF(sc, "%s: " MAC_FMT " size %u finaltsidx %u tries %u status %u rate/try %u/%u %u/%u %u/%u %u/%u\n",
-+		DPRINTF(sc, ATH_DEBUG_RATE, "%s: " MAC_FMT " size %u finaltsidx %u tries %u status %u rate/try %u/%u %u/%u %u/%u %u/%u\n",
- 			dev_info, MAC_ADDR(an->an_node.ni_macaddr),
- 			bin_to_size(size_to_bin(frame_size)),
- 			finalTSIdx,
-@@ -886,15 +869,16 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- 			if ((ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL) == vap->iv_fixed_rate)
- 				srate = x;
- 
--		KASSERT(((ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) == vap->iv_fixed_rate),
--			("fixed rate %u not in rate set", vap->iv_fixed_rate));
--
- 		sn->static_rate_ndx = srate;
- 		ni->ni_txrate = srate;
--		DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s " MAC_FMT " fixed rate %u%sMbps\n",
--			dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
--			sn->rates[srate].rate / 2,
--			(sn->rates[srate].rate % 0x1) ? ".5" : " ");
-+
-+		if ((ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate)
-+			EPRINTF(sc, "Invalid static rate, falling back to basic rate\n");
-+		else
-+			DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s " MAC_FMT " fixed rate %u%sMbps\n",
-+				dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
-+				sn->rates[srate].rate / 2,
-+				(sn->rates[srate].rate % 0x1) ? ".5" : " ");
- 		return;
- 	}
- 
diff --git a/package/madwifi/patches/380-noderef_hack.patch b/package/madwifi/patches/380-noderef_hack.patch
deleted file mode 100644
index 7c082d4143..0000000000
--- a/package/madwifi/patches/380-noderef_hack.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -427,8 +427,8 @@ ieee80211_reset_bss(struct ieee80211vap
- 			  __func__, ni, MAC_ADDR(vap->iv_myaddr));
- 	KASSERT(ni != NULL, ("unable to setup inital BSS node"));
- 
--	vap->iv_bss = PASS_NODE(ni);
--	KASSERT((atomic_read(&vap->iv_bss->ni_refcnt) == 2), 
-+	vap->iv_bss = ieee80211_ref_node(ni);
-+	KASSERT((atomic_read(&vap->iv_bss->ni_refcnt) == 3), 
- 		("wrong refcount for new node."));
- 
- 	if (obss != NULL) {
diff --git a/package/madwifi/patches/381-ibss_modes.patch b/package/madwifi/patches/381-ibss_modes.patch
deleted file mode 100644
index 38969b0532..0000000000
--- a/package/madwifi/patches/381-ibss_modes.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -1260,7 +1260,10 @@ ath_vap_create(struct ieee80211com *ic,
- 	case IEEE80211_M_IBSS:
- 		if ((sc->sc_nvaps != 0) && (ic->ic_opmode == IEEE80211_M_STA))
- 			return NULL;
--		ic_opmode = opmode;
-+		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
-+			ic_opmode = ic->ic_opmode;
-+		else
-+			ic_opmode = opmode;
- 		break;
- 	case IEEE80211_M_AHDEMO:
- 	case IEEE80211_M_MONITOR:
-@@ -1455,7 +1458,7 @@ ath_vap_create(struct ieee80211com *ic,
- 	 * frames.  Other modes carry over directly to the HAL.
- 	 */
- 	if (ic->ic_opmode == IEEE80211_M_AHDEMO)
--		sc->sc_opmode = HAL_M_IBSS;
-+		sc->sc_opmode = HAL_M_HOSTAP;
- 	else
- 		sc->sc_opmode = (HAL_OPMODE) ic->ic_opmode;	/* NB: compatible */
- 
diff --git a/package/madwifi/patches/382-relax_bintval.patch b/package/madwifi/patches/382-relax_bintval.patch
deleted file mode 100644
index 0901949d91..0000000000
--- a/package/madwifi/patches/382-relax_bintval.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -61,8 +61,8 @@
- #define	IEEE80211_DTIM_MIN		1	/* min DTIM period */
- #define	IEEE80211_DTIM_DEFAULT		1	/* default DTIM period */
- 
--#define	IEEE80211_BINTVAL_MAX		1000	/* max beacon interval (TUs) */
--#define	IEEE80211_BINTVAL_MIN		25	/* min beacon interval (TUs) */
-+#define	IEEE80211_BINTVAL_MAX		5000	/* max beacon interval (TUs) */
-+#define	IEEE80211_BINTVAL_MIN		10	/* min beacon interval (TUs) */
- #define	IEEE80211_BINTVAL_DEFAULT 	100	/* default beacon interval (TUs) */
- #define IEEE80211_BINTVAL_VALID(_bi) \
- 	((IEEE80211_BINTVAL_MIN <= (_bi)) && \
diff --git a/package/madwifi/patches/383-ibss_hostap.patch b/package/madwifi/patches/383-ibss_hostap.patch
deleted file mode 100644
index d449c3037a..0000000000
--- a/package/madwifi/patches/383-ibss_hostap.patch
+++ /dev/null
@@ -1,105 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -1452,6 +1452,23 @@ ath_vap_create(struct ieee80211com *ic,
- 		sc->sc_nstavaps++;
- 	else if (opmode == IEEE80211_M_MONITOR)
- 		sc->sc_nmonvaps++;
-+
-+
-+	/* Driving the HAL in IBSS sometimes adapts the TSF and other timing registers
-+	 * from received beacons/probes. If that happens, expected TX interrupts may
-+	 * not occur until next reset. Which triggers the "lost beacon" tasklet.
-+	 * Resulting effectively in not sending packets for minutes. Because that only
-+	 * happens in large mesh networks, this mode needs to be activated by a kernel
-+	 * module parameter: hostap_for_ibss=1. Note that using this mode has side
-+	 * effects. Such as not supressing beacons/probe answers randomly when
-+	 * receiving other node beacons. It's recommended to lower the beacon interval
-+	 * then. When using an IBSS-VAP together with an HOSTAP-VAP, you may also need
-+	 * to re-trigger IBSS beacon generation after creating the HOSTAP-VAP by
-+	 * issueing "iwpriv athX bintval 1000".
-+	 */
-+	if ((flags & IEEE80211_NO_STABEACONS) && (ic->ic_opmode == IEEE80211_M_IBSS))
-+		sc->sc_opmode = HAL_M_HOSTAP;
-+	else
- 	/*
- 	 * Adhoc demo mode is a pseudo mode; to the HAL it's
- 	 * just IBSS mode and the driver doesn't use management
-@@ -4279,7 +4296,8 @@ ath_calcrxfilter(struct ath_softc *sc)
- 	if (ic->ic_opmode != IEEE80211_M_HOSTAP && (dev->flags & IFF_PROMISC))
- 		rfilt |= HAL_RX_FILTER_PROM;
- 	if (ic->ic_opmode == IEEE80211_M_STA ||
--	    sc->sc_opmode == HAL_M_IBSS ||	/* NB: AHDEMO too */
-+	    ic->ic_opmode == IEEE80211_M_IBSS ||
-+	    ic->ic_opmode == IEEE80211_M_AHDEMO ||
- 	    (sc->sc_nostabeacons) || sc->sc_scanning ||
- 		(ic->ic_opmode == IEEE80211_M_HOSTAP))
- 		rfilt |= HAL_RX_FILTER_BEACON;
-@@ -6435,6 +6453,33 @@ ath_capture(struct net_device *dev, cons
- }
- 
- /*
-+ * Advances (forwards/adds) a microsecond value to current chip's TSF registers
-+ */
-+
-+/* from ath_info.c */
-+#define AR5K_TSF_L32_5210		0x806c	/* TSF (lower 32 bits) */
-+#define AR5K_TSF_L32_5211		0x804c
-+#define AR5K_TSF_L32			(ar_device(ah->ah_sc->devid) == 5210 ? \
-+					AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
-+
-+#define AR5K_TSF_U32_5210		0x8070
-+#define AR5K_TSF_U32_5211		0x8050
-+#define AR5K_TSF_U32			(ar_device(ah->ah_sc->devid) == 5210 ? \
-+					AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
-+
-+static inline void ath_hal_settsf64(struct ath_hal *ah, u_int64_t tsf_adv)
-+{
-+	ATH_HAL_LOCK_IRQ(ah->ah_sc);
-+	ath_hal_set_function(__func__);
-+	tsf_adv += ah->ah_getTsf64(ah);
-+	OS_REG_WRITE(ah, AR5K_TSF_L32, 0ll);
-+	OS_REG_WRITE(ah, AR5K_TSF_U32, (tsf_adv >> 32) & 0xffffffffll);
-+	OS_REG_WRITE(ah, AR5K_TSF_L32, (tsf_adv >> 00) & 0xffffffffll);
-+	ath_hal_set_function(NULL);
-+	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
-+}
-+
-+/*
-  * Intercept management frames to collect beacon RSSI data and to do
-  * ibss merges. This function is called for all management frames,
-  * including those belonging to other BSS.
-@@ -6487,10 +6532,19 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 			DPRINTF(sc, ATH_DEBUG_BEACON, 
- 				"Updated beacon timers\n");
- 		}
--		if ((sc->sc_opmode == HAL_M_IBSS) &&
--				IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid) &&
--				ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval)) {
--			DPRINTF(sc, ATH_DEBUG_ANY, "Fixed ATIM window after beacon recv\n");
-+		if ((vap->iv_opmode == IEEE80211_M_IBSS) &&
-+				(sc->sc_opmode == HAL_M_HOSTAP) &&
-+				IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) {
-+			/* In this mode, we drive the HAL in HOSTAP mode. Hence
-+			 * we do the IBSS merging in software. Also do not merge
-+			 * if the difference it too small. Otherwise we are playing
-+			 * tsf-pingpong with other vendors drivers */
-+			beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf);
-+			if (beacon_tsf > rtsf + 0xffff) {
-+				ath_hal_settsf64(sc->sc_ah, beacon_tsf - rtsf);
-+				ieee80211_ibss_merge(ni);
-+			}
-+			break;
- 		}
- 		/* NB: Fall Through */
- 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
-@@ -6563,6 +6617,10 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- #endif
- 			if (do_merge)
- 				ieee80211_ibss_merge(ni);
-+
-+			if ((sc->sc_opmode == HAL_M_IBSS) &&
-+					ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval))
-+				DPRINTF(sc, ATH_DEBUG_ANY, "Fixed ATIM window after beacon recv\n");
- 		}
- 		break;
- 	}
diff --git a/package/madwifi/patches/384-hwdetect.patch b/package/madwifi/patches/384-hwdetect.patch
deleted file mode 100644
index 3b67615b05..0000000000
--- a/package/madwifi/patches/384-hwdetect.patch
+++ /dev/null
@@ -1,325 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -62,6 +62,7 @@
- #include <linux/if_arp.h>
- #include <linux/rtnetlink.h>
- #include <linux/time.h>
-+#include <linux/pci.h>
- #include <asm/uaccess.h>
- 
- #include "if_ethersubr.h"		/* for ETHER_IS_MULTICAST */
-@@ -401,6 +402,15 @@ static int outdoor = -1;
- static int xchanmode = -1;
- static int beacon_cal = 1;
- 
-+static const struct ath_hw_detect generic_hw_info = {
-+	.vendor_name = "Unknown",
-+	.card_name = "Generic",
-+	.vendor = PCI_ANY_ID,
-+	.id = PCI_ANY_ID,
-+	.subvendor = PCI_ANY_ID,
-+	.subid = PCI_ANY_ID
-+};
-+
- static const char *hal_status_desc[] = {
- 	"No error",
- 	"No hardware present or device not yet supported",
-@@ -542,6 +552,8 @@ ath_attach(u_int16_t devid, struct net_d
- 	DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
- #endif
- 
-+	sc->sc_hwinfo = &generic_hw_info;
-+
- 	/* Allocate space for dynamically determined maximum VAP count */
- 	sc->sc_bslot = 
- 		kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
-@@ -1508,6 +1520,29 @@ ath_vap_create(struct ieee80211com *ic,
- 	return vap;
- }
- 
-+void
-+ath_hw_detect(struct ath_softc *sc, const struct ath_hw_detect *cards, int n_cards, u32 vendor, u32 id, u32 subvendor, u32 subid)
-+{
-+	int i;
-+
-+	for (i = 0; i < n_cards; i++) {
-+		const struct ath_hw_detect *c = &cards[i];
-+
-+		if ((c->vendor != PCI_ANY_ID) && c->vendor != vendor)
-+			continue;
-+		if ((c->id != PCI_ANY_ID) && c->id != id)
-+			continue;
-+		if ((c->subvendor != PCI_ANY_ID) && c->subvendor != subvendor)
-+			continue;
-+		if ((c->subid != PCI_ANY_ID) && c->subid != subid)
-+			continue;
-+
-+		sc->sc_hwinfo = c;
-+		sc->sc_poweroffset = c->poweroffset;
-+		break;
-+	}
-+}
-+
- static void
- ath_vap_delete(struct ieee80211vap *vap)
- {
-@@ -10225,6 +10260,7 @@ static u_int32_t
- ath_set_clamped_maxtxpower(struct ath_softc *sc, 
- 		u_int32_t new_clamped_maxtxpower)
- {
-+	new_clamped_maxtxpower -= sc->sc_poweroffset;
- 	(void)ath_hal_settxpowlimit(sc->sc_ah, new_clamped_maxtxpower);
- 	return ath_get_clamped_maxtxpower(sc);
- }
-@@ -10238,6 +10274,7 @@ ath_get_clamped_maxtxpower(struct ath_so
- {
- 	u_int32_t clamped_maxtxpower;
- 	(void)ath_hal_getmaxtxpow(sc->sc_ah, &clamped_maxtxpower);
-+	clamped_maxtxpower += sc->sc_poweroffset;
- 	return clamped_maxtxpower;
- }
- 
-@@ -10821,6 +10858,12 @@ ath_ioctl(struct net_device *dev, struct
-  * is to add module parameters.
-  */
- 
-+/* sysctls for hardware info */
-+enum {
-+	ATH_CARD_VENDOR,
-+	ATH_CARD_NAME,
-+};
-+
- /*
-  * Dynamic (i.e. per-device) sysctls.  These are automatically
-  * mirrored in /proc/sys.
-@@ -10900,6 +10943,38 @@ ath_sysctl_get_intmit(struct ath_softc *
- }
- 
- static int
-+ATH_SYSCTL_DECL(ath_sysctl_hwinfo, ctl, write, filp, buffer, lenp, ppos)
-+{
-+	struct ath_softc *sc = ctl->extra1;
-+	struct ath_hal *ah = sc->sc_ah;
-+	int ret = 0;
-+
-+	if (write)
-+		return -EINVAL;
-+
-+	ATH_LOCK(sc);
-+	switch((long)ctl->extra2) {
-+	case ATH_CARD_VENDOR:
-+		ctl->data = (char *)sc->sc_hwinfo->vendor_name;
-+		break;
-+	case ATH_CARD_NAME:
-+		ctl->data = (char *)sc->sc_hwinfo->card_name;
-+		break;
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+	if (ret == 0) {
-+		ctl->maxlen = strlen(ctl->data);
-+		ret = ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp,
-+				buffer, lenp, ppos);
-+	}
-+	ATH_UNLOCK(sc);
-+
-+	return ret;
-+}
-+
-+static int
- ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
- {
- 	struct ath_softc *sc = ctl->extra1;
-@@ -11179,6 +11254,24 @@ static int maxint = 0x7fffffff;		/* 32-b
- 
- static const ctl_table ath_sysctl_template[] = {
- 	{ .ctl_name	= CTL_AUTO,
-+	  .procname	= "dev_vendor",
-+	  .mode		= 0644,
-+	  .proc_handler	= ath_sysctl_hwinfo,
-+	  .strategy   = &sysctl_string,
-+	  .data		= "N/A",
-+	  .maxlen   = 1,
-+	  .extra2	= (void *)ATH_CARD_VENDOR,
-+	},
-+	{ .ctl_name	= CTL_AUTO,
-+	  .procname	= "dev_name",
-+	  .mode		= 0644,
-+	  .proc_handler	= ath_sysctl_hwinfo,
-+	  .strategy   = &sysctl_string,
-+	  .data		= "N/A",
-+	  .maxlen   = 1,
-+	  .extra2	= (void *)ATH_CARD_NAME,
-+	},
-+	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "slottime",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -168,12 +168,16 @@ static inline struct net_device *_alloc_
- 	  void __user *buffer, size_t *lenp)
- #define	ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
- 	proc_dointvec(ctl, write, filp, buffer, lenp)
-+#define	ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
-+	proc_dostring(ctl, write, filp, buffer, lenp)
- #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) */
- #define	ATH_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
- 	f(ctl_table *ctl, int write, struct file *filp, \
- 	  void __user *buffer, size_t *lenp, loff_t *ppos)
- #define	ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
- 	proc_dointvec(ctl, write, filp, buffer, lenp, ppos)
-+#define	ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
-+	proc_dostring(ctl, write, filp, buffer, lenp, ppos)
- #endif
- 
- #define	ATH_TIMEOUT	1000
-@@ -469,6 +473,7 @@ struct ath_hal;
- struct ath_desc;
- struct ath_ratectrl;
- struct ath_tx99;
-+struct ath_hw_detect;
- struct proc_dir_entry;
- 
- /*
-@@ -629,6 +634,7 @@ struct ath_softc {
- 	struct ath_ratectrl *sc_rc;		/* tx rate control support */
- 	struct ath_tx99 *sc_tx99; 		/* tx99 support */
- 	void (*sc_setdefantenna)(struct ath_softc *, u_int);
-+	const struct ath_hw_detect *sc_hwinfo;
- 
- 	unsigned int 	sc_invalid:1;		/* being detached */
- 	unsigned int	sc_mrretry:1;		/* multi-rate retry support */
-@@ -683,6 +689,7 @@ struct ath_softc {
- 	const HAL_RATE_TABLE *sc_quarter_rates;	/* quarter rate table */
- 	HAL_OPMODE sc_opmode;			/* current hal operating mode */
- 	enum ieee80211_phymode sc_curmode;	/* current phy mode */
-+	u_int sc_poweroffset;			/* hardware power offset */
- 	u_int16_t sc_curtxpow;			/* current tx power limit */
- 	u_int16_t sc_curaid;			/* current association id */
- 	HAL_CHANNEL sc_curchan;			/* current h/w channel */
-@@ -929,4 +936,16 @@ int ar_device(int devid);
- 
- void ath_radar_detected(struct ath_softc *sc, const char* message);
- 
-+struct ath_hw_detect {
-+	const char *vendor_name;
-+	const char *card_name;
-+	u32 vendor;
-+	u32 id;
-+	u32 subvendor;
-+	u32 subid;
-+	u32 poweroffset;
-+};
-+
-+extern void ath_hw_detect(struct ath_softc *sc, const struct ath_hw_detect *cards, int n_cards, u32 vendor, u32 id, u32 subvendor, u32 subid);
-+
- #endif /* _DEV_ATH_ATHVAR_H */
---- a/ath/if_ath_ahb.c
-+++ b/ath/if_ath_ahb.c
-@@ -20,6 +20,7 @@
- #include <linux/netdevice.h>
- #include <linux/cache.h>
- #include <linux/platform_device.h>
-+#include <linux/pci.h>
- 
- #include <asm/io.h>
- #include <asm/uaccess.h>
-@@ -181,12 +182,32 @@ exit_ath_wmac(u_int16_t wlanNum, struct
- 	return 0;
- }
- 
-+static const char ubnt[] = "Ubiquiti Networks";
-+/* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
-+static const struct ath_hw_detect cards[] = {
-+	{ ubnt, "PowerStation2 (18V)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb102 },
-+	{ ubnt, "PowerStation2 (16D)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb202 },
-+	{ ubnt, "PowerStation2 (EXT)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb302 },
-+	{ ubnt, "PowerStation5 (22V)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb105 },
-+	{ ubnt, "PowerStation5 (EXT)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb305 },
-+	{ ubnt, "WispStation5",        PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xa105 },
-+	{ ubnt, "LiteStation2",        PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xa002 },
-+	{ ubnt, "LiteStation5",        PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xa005 },
-+	{ ubnt, "NanoStation2",        PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc002 },
-+	{ ubnt, "NanoStation5",        PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc005 },
-+	{ ubnt, "NanoStation Loco2",   PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc102 },
-+	{ ubnt, "NanoStation Loco5",   PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc105 },
-+	{ ubnt, "Bullet2",             PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc202 },
-+	{ ubnt, "Bullet5",             PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc205 },
-+};
-+
- static int
- init_ath_wmac(u_int16_t devid, u_int16_t wlanNum, struct ar531x_config *config)
- {
- 	const char *athname;
- 	struct net_device *dev;
- 	struct ath_ahb_softc *sc;
-+	u16 *radio_data;
- 
- 	if (((wlanNum != 0) && (wlanNum != 1)) ||
- 		(sclist[wlanNum] != NULL))
-@@ -248,6 +269,16 @@ init_ath_wmac(u_int16_t devid, u_int16_t
- 	sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
- 	sc->aps_sc.sc_ledpin = config->board->sysLedGpio;
- 	sc->aps_sc.sc_invalid = 0;
-+	radio_data = (u16 *) config->radio;
-+	if (radio_data) {
-+		u16 vendor, id, subvendor, subid;
-+		vendor = radio_data[1];
-+		id = radio_data[0];
-+		subvendor = radio_data[8];
-+		subid = radio_data[7];
-+		ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
-+	}
-+
- 	return 0;
- 
-  bad4:
---- a/ath/if_ath_pci.c
-+++ b/ath/if_ath_pci.c
-@@ -123,6 +123,33 @@ static u16 ath_devidmap[][2] = {
- 	{ 0xff1a, 0x001a }
- };
- 
-+static const char ubnt[] = "Ubiquiti Networks";
-+/* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
-+static const struct ath_hw_detect cards[] = {
-+	{ ubnt, "XR2",     0x168c, 0x001b, 0x0777, 0x3002, 10 },
-+	{ ubnt, "XR2",     0x168c, 0x001b, 0x7777, 0x3002, 10 },
-+	{ ubnt, "XR2.3",   0x168c, 0x001b, 0x0777, 0x3b02, 10 },
-+	{ ubnt, "XR2.6",   0x168c, 0x001b, 0x0777, 0x3c02, 10 },
-+	{ ubnt, "XR3-2.8", 0x168c, 0x001b, 0x0777, 0x3b03, 10 },
-+	{ ubnt, "XR3-3.6", 0x168c, 0x001b, 0x0777, 0x3c03, 10 },
-+	{ ubnt, "XR3",     0x168c, 0x001b, 0x0777, 0x3003, 10 },
-+	{ ubnt, "XR4",     0x168c, 0x001b, 0x0777, 0x3004, 10 },
-+	{ ubnt, "XR5",     0x168c, 0x001b, 0x0777, 0x3005, 10 },
-+	{ ubnt, "XR5",     0x168c, 0x001b, 0x7777, 0x3005, 10 },
-+	{ ubnt, "XR7",     0x168c, 0x001b, 0x0777, 0x3007, 10 },
-+	{ ubnt, "XR9",     0x168c, 0x001b, 0x0777, 0x3009, 10 },
-+	{ ubnt, "SRC",     0x168c, 0x0013, 0x168c, 0x1042, 1 },
-+	{ ubnt, "SR2",     0x168c, 0x0013, 0x0777, 0x2041, 10 },
-+	{ ubnt, "SR4",     0x168c, 0x0013, 0x0777, 0x2004, 6 },
-+	{ ubnt, "SR4",     0x168c, 0x0013, 0x7777, 0x2004, 6 },
-+	{ ubnt, "SR4C",    0x168c, 0x0013, 0x0777, 0x1004, 6 },
-+	{ ubnt, "SR4C",    0x168c, 0x0013, 0x7777, 0x1004, 6 },
-+	{ ubnt, "SR5",     0x168c, 0x0013, 0x168c, 0x2042, 7 },
-+	{ ubnt, "SR9",     0x168c, 0x0013, 0x7777, 0x2009, 12 },
-+	{ ubnt, "SR71A",   0x168c, 0x0027, 0x168c, 0x2082, 10 },
-+	{ ubnt, "SR71",    0x168c, 0x0027, 0x0777, 0x4082, 10 },
-+};
-+
- static int
- ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
- {
-@@ -257,6 +284,10 @@ ath_pci_probe(struct pci_dev *pdev, cons
- 	printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
- 		dev_info, dev->name, athname ? athname : "Atheros ???", phymem, dev->irq);
- 
-+	ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards),
-+		pdev->vendor, pdev->device,
-+		pdev->subsystem_vendor, pdev->subsystem_device);
-+
- 	/* ready to process interrupts */
- 	sc->aps_sc.sc_invalid = 0;
- 
diff --git a/package/madwifi/patches/385-antenna_fix.patch b/package/madwifi/patches/385-antenna_fix.patch
deleted file mode 100644
index 16c7d95c76..0000000000
--- a/package/madwifi/patches/385-antenna_fix.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -6669,6 +6669,7 @@ ath_setdefantenna(struct ath_softc *sc,
- 	struct ath_hal *ah = sc->sc_ah;
- 
- 	/* XXX block beacon interrupts */
-+	ath_hal_setdiversity(ah, (sc->sc_diversity != 0));
- 	ath_hal_setdefantenna(ah, antenna);
- 	if (sc->sc_defant != antenna)
- 		sc->sc_stats.ast_ant_defswitch++;
diff --git a/package/madwifi/patches/386-acl_crashfix.patch b/package/madwifi/patches/386-acl_crashfix.patch
deleted file mode 100644
index 04a1ec9110..0000000000
--- a/package/madwifi/patches/386-acl_crashfix.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-fixes ACL race condition caused by acl list modifications at run time
-
-Signed-off-by: Sebastian Gottschall <brainslayer@dd-wrt.com>
-
---- a/net80211/ieee80211_acl.c
-+++ b/net80211/ieee80211_acl.c
-@@ -112,9 +112,9 @@ acl_detach(struct ieee80211vap *vap)
- {
- 	struct aclstate *as = vap->iv_as;
- 
--	ACL_LOCK(as);
-+	ACL_LOCK_IRQ(as);
- 	acl_free_all_locked(as);
--	ACL_UNLOCK(as);
-+	ACL_UNLOCK_IRQ(as);
- 	vap->iv_as = NULL;
- 	ACL_LOCK_DESTROY(as);
- 	FREE(as, M_DEVBUF);
-@@ -128,11 +128,18 @@ _find_acl(struct aclstate *as, const u_i
- 	struct acl *acl;
- 	int hash;
- 
-+	/* locking needed, as inserts are not atomic */
-+	ACL_LOCK_IRQ(as);
- 	hash = ACL_HASH(macaddr);
- 	LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) {
--		if (IEEE80211_ADDR_EQ(acl->acl_macaddr, macaddr))
--			return acl;
-+		if (!IEEE80211_ADDR_EQ(acl->acl_macaddr, macaddr))
-+			continue;
-+
-+		ACL_UNLOCK_IRQ_EARLY(as);
-+		return acl;
- 	}
-+	ACL_UNLOCK_IRQ(as);
-+
- 	return NULL;
- }
- 
-@@ -176,11 +183,11 @@ acl_add(struct ieee80211vap *vap, const
- 		return -ENOMEM;
- 	}
- 
--	ACL_LOCK(as);
-+	ACL_LOCK_IRQ(as);
- 	hash = ACL_HASH(mac);
- 	LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) {
- 		if (IEEE80211_ADDR_EQ(acl->acl_macaddr, mac)) {
--			ACL_UNLOCK_EARLY(as);
-+			ACL_UNLOCK_IRQ_EARLY(as);
- 			FREE(new, M_80211_ACL);
- 			IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
- 				"ACL: add " MAC_FMT " failed, already present\n",
-@@ -191,7 +198,7 @@ acl_add(struct ieee80211vap *vap, const
- 	IEEE80211_ADDR_COPY(new->acl_macaddr, mac);
- 	TAILQ_INSERT_TAIL(&as->as_list, new, acl_list);
- 	LIST_INSERT_HEAD(&as->as_hash[hash], new, acl_hash);
--	ACL_UNLOCK(as);
-+	ACL_UNLOCK_IRQ(as);
- 
- 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
- 		"ACL: add " MAC_FMT "\n", MAC_ADDR(mac));
-@@ -204,11 +211,11 @@ acl_remove(struct ieee80211vap *vap, con
- 	struct aclstate *as = vap->iv_as;
- 	struct acl *acl;
- 
--	ACL_LOCK(as);
-+	ACL_LOCK_IRQ(as);
- 	acl = _find_acl(as, mac);
- 	if (acl != NULL)
- 		_acl_free(as, acl);
--	ACL_UNLOCK(as);
-+	ACL_UNLOCK_IRQ(as);
- 
- 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
- 		"ACL: remove " MAC_FMT "%s\n", MAC_ADDR(mac),
-@@ -235,9 +242,9 @@ acl_free_all(struct ieee80211vap *vap)
- 
- 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, "ACL: %s\n", "free all");
- 
--	ACL_LOCK(as);
-+	ACL_LOCK_IRQ(as);
- 	acl_free_all_locked(vap->iv_as);
--	ACL_UNLOCK(as);
-+	ACL_UNLOCK_IRQ(as);
- 
- 	return 0;
- }
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -319,16 +319,15 @@ typedef spinlock_t ieee80211_scan_lock_t
- typedef spinlock_t acl_lock_t;
- #define	ACL_LOCK_INIT(_as, _name)	spin_lock_init(&(_as)->as_lock)
- #define	ACL_LOCK_DESTROY(_as)
--#define	ACL_LOCK(_as)			do { 	\
--	ACL_LOCK_CHECK(_as); 		\
--	spin_lock(&(_as)->as_lock);
--#define	ACL_UNLOCK(_as)				\
--	ACL_LOCK_ASSERT(_as); 			\
--	spin_unlock(&(_as)->as_lock); 		\
--} while(0)
--#define ACL_UNLOCK_EARLY(_as)			\
--	ACL_LOCK_ASSERT(_as); 			\
--	spin_unlock(&(_as)->as_lock);
-+#define	ACL_LOCK_IRQ(_as)	do {	\
-+	unsigned long __acl_lockflags;		\
-+	spin_lock_irqsave(&(_as)->as_lock, __acl_lockflags);
-+#define	ACL_UNLOCK_IRQ(_as) \
-+	spin_unlock_irqrestore(&(_as)->as_lock, __acl_lockflags); \
-+} while (0)
-+#define	ACL_UNLOCK_IRQ_EARLY(_as)	do { \
-+	spin_unlock_irqrestore(&(_as)->as_lock, __acl_lockflags); \
-+} while (0)
- 
- #if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
- #define	ACL_LOCK_ASSERT(_as) \
diff --git a/package/madwifi/patches/387-maxassoc.patch b/package/madwifi/patches/387-maxassoc.patch
deleted file mode 100644
index 79e5b2f4fc..0000000000
--- a/package/madwifi/patches/387-maxassoc.patch
+++ /dev/null
@@ -1,85 +0,0 @@
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -198,6 +198,7 @@ struct ieee80211vap {
- 	u_int32_t iv_debug;				/* debug msg flags */
- 	struct ieee80211_stats iv_stats;		/* statistics */
- 
-+	int iv_max_nodes;
- 	int iv_monitor_nods_only;			/* in monitor mode only nods traffic */
- 	int iv_monitor_txf_len;				/* in monitor mode, truncate tx packets */
- 	int iv_monitor_phy_errors;			/* in monitor mode, accept phy errors */
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -650,6 +650,7 @@ enum {
- 	IEEE80211_PARAM_RSSI_DIS_THR	= 80,	/* rssi threshold for disconnection */
- 	IEEE80211_PARAM_RSSI_DIS_COUNT	= 81,	/* counter for rssi threshold */
- 	IEEE80211_PARAM_WDS_SEP			= 82,	/* move wds stations into separate interfaces */
-+	IEEE80211_PARAM_MAXASSOC		= 83,	/* maximum associated stations */
- };
- 
- #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2875,6 +2875,12 @@ ieee80211_ioctl_setparam(struct net_devi
- 		else
- 			vap->iv_flags_ext &= ~IEEE80211_FEXT_WDSSEP;
- 		break;
-+	case IEEE80211_PARAM_MAXASSOC:
-+		if (vap->iv_opmode != IEEE80211_M_HOSTAP)
-+			retv = -EINVAL;
-+		else
-+			vap->iv_max_nodes = value;
-+		break;
- #ifdef ATH_REVERSE_ENGINEERING
- 	case IEEE80211_PARAM_DUMPREGS:
- 		ieee80211_dump_registers(dev, info, w, extra);
-@@ -3234,6 +3240,9 @@ ieee80211_ioctl_getparam(struct net_devi
- 	case IEEE80211_PARAM_WDS_SEP:
- 		param[0] = !!(vap->iv_flags_ext & IEEE80211_FEXT_WDSSEP);
- 		break;
-+	case IEEE80211_PARAM_MAXASSOC:
-+		param[0] = vap->iv_max_nodes;
-+		break;
- 	default:
- 		return -EOPNOTSUPP;
- 	}
-@@ -5789,6 +5798,10 @@ static const struct iw_priv_args ieee802
- 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wdssep"},
- 	{ IEEE80211_PARAM_WDS_SEP,
- 	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_wdssep"},
-+	{ IEEE80211_PARAM_MAXASSOC,
-+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxassoc"},
-+	{ IEEE80211_PARAM_MAXASSOC,
-+	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxassoc"},
- 
- #ifdef ATH_REVERSE_ENGINEERING
- 	/*
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -4020,7 +4020,26 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			vap->iv_stats.is_rx_assoc_norate++;
- 			return;
- 		}
-+		if (vap->iv_max_nodes > 0) {
-+			unsigned int active_nodes = 0;
-+			struct ieee80211_node *tni;
- 
-+			IEEE80211_NODE_TABLE_LOCK_IRQ(&ic->ic_sta);
-+			TAILQ_FOREACH(tni, &ic->ic_sta.nt_node, ni_list) {
-+				if (tni->ni_vap != vap)
-+					continue;
-+				if (tni->ni_associd == 0)
-+					continue;
-+				active_nodes++;
-+			}
-+			IEEE80211_NODE_TABLE_UNLOCK_IRQ(&ic->ic_sta);
-+
-+			if (active_nodes >= vap->iv_max_nodes) {
-+				/* too many nodes connected */
-+				ieee80211_node_leave(ni);
-+				return;
-+			}
-+		}
- 		if (ni->ni_associd != 0 &&
- 		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) {
- 			if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)
diff --git a/package/madwifi/patches/388-apsta_fix.patch b/package/madwifi/patches/388-apsta_fix.patch
deleted file mode 100644
index b0cb8e9dff..0000000000
--- a/package/madwifi/patches/388-apsta_fix.patch
+++ /dev/null
@@ -1,60 +0,0 @@
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -1415,7 +1415,8 @@ __ieee80211_newstate(struct ieee80211vap
- 	vap->iv_state = nstate;			/* state transition */
- 	del_timer(&vap->iv_mgtsend);
- 	if ((vap->iv_opmode != IEEE80211_M_HOSTAP) && 
--			(ostate != IEEE80211_S_SCAN))
-+			(ostate != IEEE80211_S_SCAN) &&
-+			!(vap->iv_flags_ext & IEEE80211_FEXT_SCAN_PENDING))
- 		ieee80211_cancel_scan(vap);	/* background scan */
- 	ni = vap->iv_bss;			/* NB: no reference held */
- 	switch (nstate) {
-@@ -1457,7 +1458,8 @@ __ieee80211_newstate(struct ieee80211vap
- 			}
- 			goto reset;
- 		case IEEE80211_S_SCAN:
--			ieee80211_cancel_scan(vap);
-+			if (!(vap->iv_flags_ext & IEEE80211_FEXT_SCAN_PENDING))
-+				ieee80211_cancel_scan(vap);
- 			goto reset;
- 		reset:
- 			ieee80211_reset_bss(vap);
-@@ -1995,7 +1997,9 @@ ieee80211_newstate(struct ieee80211vap *
- 					}
- 				}
- 			}
--		} else if (dstate == IEEE80211_S_SCAN) {
-+		} else if ((dstate == IEEE80211_S_SCAN) ||
-+				(dstate == IEEE80211_S_AUTH) ||
-+				(dstate == IEEE80211_S_ASSOC)) {
- 			/* Force to scan pending... someone is scanning */
- 			vap->iv_flags_ext |= IEEE80211_FEXT_SCAN_PENDING;
- 			__ieee80211_newstate(vap, IEEE80211_S_INIT, arg);
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -238,7 +238,9 @@ ieee80211_hardstart(struct sk_buff *skb,
- 	}
- 	
- 	/* Cancel any running BG scan */
--	if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && (vap->iv_state == IEEE80211_S_RUN))
-+	if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) &&
-+		(vap->iv_state == IEEE80211_S_RUN) &&
-+		(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN))
- 		ieee80211_cancel_scan(vap);
- 
- 	/* 
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2728,9 +2728,9 @@ ieee80211_ioctl_setparam(struct net_devi
- 				return -EINVAL;
- 			vap->iv_flags |= IEEE80211_F_BGSCAN;
- 		} else {
--			/* XXX racey? */
-+			if (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN)
-+				ieee80211_cancel_scan(vap);	/* anything current */
- 			vap->iv_flags &= ~IEEE80211_F_BGSCAN;
--			ieee80211_cancel_scan(vap);	/* anything current */
- 		}
- 		break;
- 	case IEEE80211_PARAM_BGSCAN_IDLE:
diff --git a/package/madwifi/patches/389-autochannel.patch b/package/madwifi/patches/389-autochannel.patch
deleted file mode 100644
index 548f09e7d6..0000000000
--- a/package/madwifi/patches/389-autochannel.patch
+++ /dev/null
@@ -1,249 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -384,6 +384,7 @@ static u_int32_t ath_get_real_maxtxpower
- 
- static void ath_poll_disable(struct net_device *dev);
- static void ath_poll_enable(struct net_device *dev);
-+static void ath_fetch_idle_time(struct ath_softc *sc);
- 
- /* calibrate every 30 secs in steady state but check every second at first. */
- static int ath_calinterval = ATH_SHORT_CALINTERVAL;
-@@ -2581,6 +2582,7 @@ ath_init(struct net_device *dev)
- 	 * be followed by initialization of the appropriate bits
- 	 * and then setup of the interrupt mask.
- 	 */
-+	ath_fetch_idle_time(sc);
- 	sc->sc_curchan.channel = ic->ic_curchan->ic_freq;
- 	sc->sc_curchan.channelFlags = ath_chan2flags(ic->ic_curchan);
- 	if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_FALSE, &status)) {
-@@ -2914,6 +2916,48 @@ ath_hw_check_atim(struct ath_softc *sc,
- 	return 0;
- }
- 
-+#define AR5K_MIBC       0x0040
-+#define AR5K_MIBC_FREEZE   (1 << 1)
-+#define AR5K_TXFC       0x80ec
-+#define AR5K_RXFC       0x80f0
-+#define AR5K_RXCLEAR	0x80f4
-+#define AR5K_CYCLES		0x80f8
-+static void
-+ath_fetch_idle_time(struct ath_softc *sc)
-+{
-+	struct ieee80211com *ic = &sc->sc_ic;
-+	struct ath_hal *ah = sc->sc_ah;
-+	u_int32_t cc, rx;
-+	u_int32_t time = 0;
-+
-+	if (sc->sc_ah->ah_macType < 5212)
-+		return;
-+
-+	if (!ic->ic_curchan || (ic->ic_curchan == IEEE80211_CHAN_ANYC))
-+		return;
-+
-+	OS_REG_WRITE(ah, AR5K_MIBC, AR5K_MIBC_FREEZE);
-+	rx = OS_REG_READ(ah, AR5K_RXCLEAR);
-+	cc = OS_REG_READ(ah, AR5K_CYCLES);
-+
-+	if (!cc)
-+		return;
-+
-+	if (rx > cc)
-+		return; /* should not happen */
-+
-+	if (sc->sc_last_chan)
-+		sc->sc_last_chan->ic_idletime = 100 * (cc - rx) / cc;
-+	sc->sc_last_chan = ic->ic_curchan;
-+
-+	OS_REG_WRITE(ah, AR5K_RXCLEAR, 0);
-+	OS_REG_WRITE(ah, AR5K_CYCLES, 0);
-+	OS_REG_WRITE(ah, AR5K_TXFC, 0);
-+	OS_REG_WRITE(ah, AR5K_RXFC, 0);
-+	OS_REG_WRITE(ah, AR5K_MIBC, 0);
-+}
-+#undef AR5K_RXCLEAR
-+#undef AR5K_CYCLES
- 
- /*
-  * Reset the hardware w/o losing operational state.  This is
-@@ -2941,6 +2985,7 @@ ath_reset(struct net_device *dev)
- 	 * Convert to a HAL channel description with the flags
- 	 * constrained to reflect the current operating mode.
- 	 */
-+	ath_fetch_idle_time(sc);
- 	c = ic->ic_curchan;
- 	sc->sc_curchan.channel = c->ic_freq;
- 	sc->sc_curchan.channelFlags = ath_chan2flags(c);
-@@ -9023,6 +9068,7 @@ ath_chan_set(struct ath_softc *sc, struc
- 	u_int8_t channel_change_required = 0;
- 	struct timeval tv;
- 
-+
- 	/*
- 	 * Convert to a HAL channel description with
- 	 * the flags constrained to reflect the current
-@@ -9031,6 +9077,14 @@ ath_chan_set(struct ath_softc *sc, struc
- 	memset(&hchan, 0, sizeof(HAL_CHANNEL));
- 	hchan.channel = chan->ic_freq;
- 	hchan.channelFlags = ath_chan2flags(chan);
-+
-+	/* don't do duplicate channel changes, but do
-+	 * store the available idle time */
-+	ath_fetch_idle_time(sc);
-+	if ((sc->sc_curchan.channel == hchan.channel) &&
-+		(sc->sc_curchan.channelFlags == hchan.channelFlags))
-+		return 0;
-+
- 	KASSERT(hchan.channel != 0,
- 		("bogus channel %u/0x%x", hchan.channel, hchan.channelFlags));
- 	do_gettimeofday(&tv);
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -774,6 +774,7 @@ struct ath_softc {
- 	struct ieee80211vap **sc_bslot;		/* beacon xmit slots */
- 	int sc_bnext;				/* next slot for beacon xmit */
- 
-+	struct ieee80211_channel *sc_last_chan;
- 	int sc_beacon_cal;			/* use beacon timer for calibration */
- 	u_int64_t sc_lastcal;			/* last time the calibration was performed */
- 	struct timer_list sc_cal_ch;		/* calibration timer */
---- a/net80211/_ieee80211.h
-+++ b/net80211/_ieee80211.h
-@@ -148,6 +148,7 @@ struct ieee80211_channel {
- 	int8_t ic_maxpower;	/* maximum tx power in dBm */
- 	int8_t ic_minpower;	/* minimum tx power in dBm */
- 	u_int8_t ic_scanflags;
-+	u_int8_t ic_idletime; /* phy idle time in % */
- };
- 
- #define	IEEE80211_CHAN_MAX	255
---- a/net80211/ieee80211_scan_ap.c
-+++ b/net80211/ieee80211_scan_ap.c
-@@ -417,6 +417,19 @@ pc_cmp_rssi(struct ap_state *as, struct
- 
- /* This function must be invoked with locks acquired */
- static int
-+pc_cmp_idletime(struct ieee80211_channel *a,
-+		struct ieee80211_channel *b)
-+{
-+	if (!a->ic_idletime || !b->ic_idletime)
-+		return 0;
-+
-+	/* a is better than b (return < 0) when a has more idle time than b */
-+	return b->ic_idletime - a->ic_idletime;
-+}
-+
-+
-+/* This function must be invoked with locks acquired */
-+static int
- pc_cmp_samechan(struct ieee80211com *ic, struct ieee80211_channel *a,
- 		struct ieee80211_channel *b)
- {
-@@ -451,6 +464,7 @@ pc_cmp(const void *_a, const void *_b)
- 
- 	EVALUATE_CRITERION(radar, a, b);
- 	EVALUATE_CRITERION(keepmode, params, a, b);
-+	EVALUATE_CRITERION(idletime, a, b);
- 	EVALUATE_CRITERION(sc, ic, a, b);
- 	/* XXX: rssi useless? pick_channel evaluates it anyway */
- 	EVALUATE_CRITERION(rssi, params->ss->ss_priv, a, b);
-@@ -519,16 +533,9 @@ pick_channel(struct ieee80211_scan_state
- #endif
- 
- 	best = NULL;
--	best_rssi = 0xff; /* If signal is bigger than 0xff, we'd be melting. */
- 
- 	for (i = 0; i < ss_last; i++) {
- 		c = &chans[i];
--		benefit = best_rssi - as->as_maxrssi[c->chan->ic_ieee];
--		sta_assoc = ic->ic_sta_assoc;
--
--		/* Don't switch... */
--		if (benefit <= 0)
--			continue;
- 
- 		/* Verify channel is not marked for non-occupancy */
- 		if (IEEE80211_IS_CHAN_RADAR(c->chan))
-@@ -546,31 +553,8 @@ pick_channel(struct ieee80211_scan_state
- 				break;
- 		}
- 
--		if (sta_assoc != 0) {
--			int sl = ic->ic_cn_total - 
--				ic->ic_chan_nodes[c->chan->ic_ieee]; /* count */
--			if (ic->ic_sc_algorithm == IEEE80211_SC_LOOSE) {
--				int sl_max = ic->ic_sc_sldg * benefit;
--				sl = 1000 * sl / sta_assoc; /* permil */
--				IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
--						"%s: chan %d, dB gained: %d, "
--						"STAs lost: %d permil (max %d)\n",
--						__func__, c->chan->ic_ieee, 
--						benefit, sl, sl_max);
--				if (sl > sl_max)
--					continue;
--			} else if (((ic->ic_sc_algorithm == 
--						 IEEE80211_SC_TIGHT) ||
--					(ic->ic_sc_algorithm == 
--						 IEEE80211_SC_STRICT)) && 
--					(sl > 0)) {
--				/* Break the loop as the subsequent chans 
--				 * won't be better. */
--				break;
--			}
--		}
- 		best = c->chan;
--		best_rssi = as->as_maxrssi[best->ic_ieee];
-+		break;
- 	}
- 
- 	if (best != NULL) {
-@@ -599,6 +583,9 @@ ap_end(struct ieee80211_scan_state *ss,
- 		("wrong opmode %u", vap->iv_opmode));
- 
- 	ic = vap->iv_ic;
-+
-+	/* record stats for the channel that was scanned last */
-+	ic->ic_set_channel(ic);
- 	bestchan = pick_channel(ss, vap, flags);
- 	if (bestchan == NULL) {
- 		if (ss->ss_last > 0) {
---- a/net80211/ieee80211_scan.c
-+++ b/net80211/ieee80211_scan.c
-@@ -1002,20 +1002,34 @@ ieee80211_scan_add_channels(struct ieee8
- {
- 	struct ieee80211_channel *c, *cg;
- 	u_int modeflags;
-+	int has_non_turbo = 0;
- 	int i;
- 
- 	KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode));
- 	modeflags = chanflags[mode];
- 	for (i = 0; i < ic->ic_nchans; i++) {
- 		c = &ic->ic_channels[i];
-+		if (c->ic_flags & (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO))
-+			continue;
-+
-+		has_non_turbo = 1;
-+		break;
-+	}
-+	for (i = 0; i < ic->ic_nchans; i++) {
-+		c = &ic->ic_channels[i];
- 		if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee))
- 			continue;
- 		if (c->ic_scanflags & IEEE80211_NOSCAN_SET)
- 			continue;
--		if (modeflags &&
--			((c->ic_flags & IEEE80211_CHAN_ALLTURBO) !=
--			 (modeflags & IEEE80211_CHAN_ALLTURBO)))
--			continue;
-+		if (modeflags) {
-+			if ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) !=
-+				 (modeflags & IEEE80211_CHAN_ALLTURBO))
-+				continue;
-+		} else if (has_non_turbo) {
-+			if ((ss->ss_vap->iv_opmode == IEEE80211_M_HOSTAP) &&
-+				(c->ic_flags & (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)))
-+				continue;
-+		}
- 		if (mode == IEEE80211_MODE_AUTO) {
- 			/*
- 			 * XXX special-case 11b/g channels so we select
diff --git a/package/madwifi/patches/390-frame_type.patch b/package/madwifi/patches/390-frame_type.patch
deleted file mode 100644
index 6de01102c6..0000000000
--- a/package/madwifi/patches/390-frame_type.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -4443,7 +4443,9 @@ ath_eth_type_trans(struct sk_buff *skb,
- 		if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN))
- 			skb->pkt_type = PACKET_OTHERHOST;
- 
--	return eth->h_proto;
-+	if ((ntohs(eth->h_proto) >= 1536) || (ntohs(eth->h_proto) < 38))
-+		return eth->h_proto;
-+	return htons(ETH_P_802_2);
- }
- #endif
- 
diff --git a/package/madwifi/patches/391-vap_auth.patch b/package/madwifi/patches/391-vap_auth.patch
deleted file mode 100644
index 832f9e1162..0000000000
--- a/package/madwifi/patches/391-vap_auth.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -1375,7 +1375,7 @@ ieee80211_auth_open(struct ieee80211_nod
- 		vap->iv_stats.is_rx_bad_auth++;	/* XXX maybe a unique error? */
- 		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
- 			if (ni == vap->iv_bss) {
--				ni = ieee80211_dup_bss(vap, wh->i_addr2, 0);
-+				ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
- 				if (ni == NULL)
- 					return;
- 				tmpnode = 1;
-@@ -1763,6 +1763,8 @@ ieee80211_ssid_mismatch(struct ieee80211
- }
- 
- #define	IEEE80211_VERIFY_SSID(_ni, _ssid) do {				\
-+	if ((_ni)->ni_esslen == 0)					\
-+		return;							\
- 	if ((_ssid)[1] != 0 &&						\
- 	    ((_ssid)[1] != (_ni)->ni_esslen ||				\
- 	    memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) {	\
-@@ -1777,6 +1779,8 @@ ieee80211_ssid_mismatch(struct ieee80211
- } while (0)
- #else /* !IEEE80211_DEBUG */
- #define	IEEE80211_VERIFY_SSID(_ni, _ssid) do {				\
-+	if ((_ni)->ni_esslen == 0)					\
-+		return;							\
- 	if ((_ssid)[1] != 0 &&						\
- 	    ((_ssid)[1] != (_ni)->ni_esslen ||				\
- 	    memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) {	\
diff --git a/package/madwifi/patches/392-remove_wds_nodetracking.patch b/package/madwifi/patches/392-remove_wds_nodetracking.patch
deleted file mode 100644
index fb9fb6a222..0000000000
--- a/package/madwifi/patches/392-remove_wds_nodetracking.patch
+++ /dev/null
@@ -1,388 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -568,36 +568,6 @@ ieee80211_input(struct ieee80211vap * va
- 				}
- 			}
- 
--			/* XXX: Useless node mgmt API; make better */
--			if ((dir == IEEE80211_FC1_DIR_DSTODS) && !vap->iv_wdsnode &&
--					!ni_wds && !ni->ni_subif) {
--				struct ieee80211_node_table *nt = &ic->ic_sta;
--				struct ieee80211_frame_addr4 *wh4;
--
--				if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS)) {
--					IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
--						wh, "data", "%s", "4 addr not allowed");
--					goto err;
--				}
--				wh4 = (struct ieee80211_frame_addr4 *)skb->data;
--				ni_wds = ieee80211_find_wds_node(nt, wh4->i_addr4);
--				/* Last call increments ref count if !NULL */
--				if ((ni_wds != NULL) && (ni_wds != ni)) {
--					/*
--					 * node with source address (addr4) moved
--					 * to another WDS capable station. remove the
--					 * reference to the previous station and add 
--					 * reference to the new one
--					 */
--					 (void) ieee80211_remove_wds_addr(nt, wh4->i_addr4);
--					 ieee80211_add_wds_addr(nt, ni, wh4->i_addr4, 0);
--				}
--				if (ni_wds == NULL)
--					ieee80211_add_wds_addr(nt, ni, wh4->i_addr4, 0);
--				else
--					ieee80211_unref_node(&ni_wds);
--			}
--
- 			/*
- 			 * Check for power save state change.
- 			 */
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -122,7 +122,6 @@ static void ieee80211_node_table_init(st
- static void ieee80211_node_table_cleanup(struct ieee80211_node_table *);
- static void ieee80211_node_table_reset(struct ieee80211_node_table *,
- 	struct ieee80211vap *);
--static void ieee80211_node_wds_ageout(unsigned long);
- 
- MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
- 
-@@ -785,10 +784,6 @@ ieee80211_node_table_init(struct ieee802
- 	nt->nt_name = name;
- 	nt->nt_scangen = 1;
- 	nt->nt_inact_init = inact;
--	init_timer(&nt->nt_wds_aging_timer);
--	nt->nt_wds_aging_timer.function = ieee80211_node_wds_ageout;
--	nt->nt_wds_aging_timer.data = (unsigned long) nt;
--	mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL);
- }
- 
- static __inline 
-@@ -1204,142 +1199,6 @@ void ieee80211_wds_addif(struct ieee8021
- 	schedule_work(&ni->ni_create);
- }
- 
--/* Add wds address to the node table */
--int
--#ifdef IEEE80211_DEBUG_REFCNT
--ieee80211_add_wds_addr_debug(struct ieee80211_node_table *nt,
--	struct ieee80211_node *ni, const u_int8_t *macaddr, u_int8_t wds_static,
--	const char* func, int line)
--#else
--ieee80211_add_wds_addr(struct ieee80211_node_table *nt,
--	struct ieee80211_node *ni, const u_int8_t *macaddr, u_int8_t wds_static)
--#endif
--{
--	int hash;
--	struct ieee80211_wds_addr *wds;
--
--	MALLOC(wds, struct ieee80211_wds_addr *, sizeof(struct ieee80211_wds_addr),
--		M_80211_WDS, M_NOWAIT | M_ZERO);
--	if (wds == NULL) {
--		/* XXX msg */
--		return 1;
--	}
--	if (wds_static)
--		wds->wds_agingcount = WDS_AGING_STATIC;
--	else
--		wds->wds_agingcount = WDS_AGING_COUNT;
--	hash = IEEE80211_NODE_HASH(macaddr);
--	IEEE80211_ADDR_COPY(wds->wds_macaddr, macaddr);
--
--	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
--#ifdef IEEE80211_DEBUG_REFCNT
--	wds->wds_ni = ieee80211_ref_node_debug(ni, func, line);
--#else
--	wds->wds_ni = ieee80211_ref_node(ni);
--#endif
--	LIST_INSERT_HEAD(&nt->nt_wds_hash[hash], wds, wds_hash);
--	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
--	return 0;
--}
--#ifdef IEEE80211_DEBUG_REFCNT
--EXPORT_SYMBOL(ieee80211_add_wds_addr_debug);
--#else
--EXPORT_SYMBOL(ieee80211_add_wds_addr);
--#endif
--
--/* remove wds address from the wds hash table */
--void
--#ifdef IEEE80211_DEBUG_REFCNT
--ieee80211_remove_wds_addr_debug(struct ieee80211_node_table *nt, const u_int8_t *macaddr, 
--			   const char* func, int line)
--#else
--ieee80211_remove_wds_addr(struct ieee80211_node_table *nt, const u_int8_t *macaddr)
--#endif
--{
--	int hash;
--	struct ieee80211_wds_addr *wds, *twds;
--
--	hash = IEEE80211_NODE_HASH(macaddr);
--	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
--	LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {
--		if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {
--			LIST_REMOVE(wds, wds_hash);
--#ifdef IEEE80211_DEBUG_REFCNT
--			ieee80211_unref_node_debug(&wds->wds_ni, func, line);
--#else
--			ieee80211_unref_node(&wds->wds_ni);
--#endif
--			FREE(wds, M_80211_WDS);
--			break;
--		}
--	}
--	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
--}
--#ifdef IEEE80211_DEBUG_REFCNT
--EXPORT_SYMBOL(ieee80211_remove_wds_addr_debug);
--#else
--EXPORT_SYMBOL(ieee80211_remove_wds_addr);
--#endif
--
--/* Remove node references from wds table */
--void
--#ifdef IEEE80211_DEBUG_REFCNT
--ieee80211_del_wds_node_debug(struct ieee80211_node_table *nt, struct ieee80211_node *ni, 
--			const char* func, int line)
--#else
--ieee80211_del_wds_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
--#endif
--{
--	int hash;
--	struct ieee80211_wds_addr *wds, *twds;
--
--	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
--	for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {
--		LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {
--			if (wds->wds_ni == ni) {
--				LIST_REMOVE(wds, wds_hash);
--#ifdef IEEE80211_DEBUG_REFCNT
--				ieee80211_unref_node_debug(&wds->wds_ni, func, line);
--#else
--				ieee80211_unref_node(&wds->wds_ni);
--#endif
--				FREE(wds, M_80211_WDS);
--			}
--		}
--	}
--	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
--}
--#ifdef IEEE80211_DEBUG_REFCNT
--EXPORT_SYMBOL(ieee80211_del_wds_node_debug);
--#else
--EXPORT_SYMBOL(ieee80211_del_wds_node);
--#endif
--
--static void
--ieee80211_node_wds_ageout(unsigned long data)
--{
--	struct ieee80211_node_table *nt = (struct ieee80211_node_table *)data;
--	int hash;
--	struct ieee80211_wds_addr *wds, *twds;
--
--	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
--	for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {
--		LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {
--			if (wds->wds_agingcount != WDS_AGING_STATIC) {
--				if (!wds->wds_agingcount) {
--					LIST_REMOVE(wds, wds_hash);
--					ieee80211_unref_node(&wds->wds_ni);
--					FREE(wds, M_80211_WDS);
--				} else
--					wds->wds_agingcount--;
--			}
--		}
--	}
--	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
--	mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL);
--}
--
--
- /* Add the specified station to the station table.
-  * Allocates a new ieee80211_node* that has a reference count of one
-  * If tmp is 0, it is added to the node table and the reference is used.
-@@ -1385,34 +1244,6 @@ ieee80211_dup_bss(struct ieee80211vap *v
- 	return ni;
- }
- 
--static struct ieee80211_node *
--#ifdef IEEE80211_DEBUG_REFCNT
--ieee80211_find_wds_node_locked_debug(struct ieee80211_node_table *nt, 
--			 const u_int8_t *macaddr, const char* func, int line)
--#else
--ieee80211_find_wds_node_locked(struct ieee80211_node_table *nt, 
--			 const u_int8_t *macaddr)
--#endif
--{
--	struct ieee80211_wds_addr *wds;
--	int hash;
--	IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
--
--	hash = IEEE80211_NODE_HASH(macaddr);
--	LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {
--		if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {
--			if (wds->wds_agingcount != WDS_AGING_STATIC)
--				wds->wds_agingcount = WDS_AGING_COUNT; /* reset the aging count */
--#ifdef IEEE80211_DEBUG_REFCNT
--			return ieee80211_ref_node_debug(wds->wds_ni, func, line);
--#else
--			return ieee80211_ref_node(wds->wds_ni);
--#endif
--		}
--	}
--	return NULL;
--}
--
- /* NB: A node reference is acquired here; the caller MUST release it. */
- #ifdef IEEE80211_DEBUG_REFCNT
- #define	ieee80211_find_node_locked(nt, mac) \
-@@ -1430,7 +1261,6 @@ ieee80211_find_node_locked(struct ieee80
- {
- 	struct ieee80211_node *ni;
- 	int hash;
--	struct ieee80211_wds_addr *wds;
- 
- 	IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
- 
-@@ -1445,48 +1275,11 @@ ieee80211_find_node_locked(struct ieee80
- 			return ni;
- 		}
- 	}
--
--	/* Now, we look for the desired mac address in the 4 address
--	   nodes. */
--	LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {
--		if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {
--#ifdef IEEE80211_DEBUG_REFCNT
--			return ieee80211_ref_node_debug(wds->wds_ni, func, line);
--#else
--			return ieee80211_ref_node(wds->wds_ni);
--#endif 
--		}
--	}
- 	return NULL;
- }
- 
- struct ieee80211_node *
- #ifdef IEEE80211_DEBUG_REFCNT
--ieee80211_find_wds_node_debug(struct ieee80211_node_table *nt, const u_int8_t *macaddr, 
--			 const char* func, int line)
--#else
--ieee80211_find_wds_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr)
--#endif
--{
--	struct ieee80211_node *ni;
--
--	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
--#ifdef IEEE80211_DEBUG_REFCNT
--	ni = ieee80211_find_wds_node_locked_debug(nt, macaddr, func, line);
--#else
--	ni = ieee80211_find_wds_node_locked(nt, macaddr);
--#endif
--	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
--	return ni;
--}
--#ifdef IEEE80211_DEBUG_REFCNT
--EXPORT_SYMBOL(ieee80211_find_wds_node_debug);
--#else
--EXPORT_SYMBOL(ieee80211_find_wds_node);
--#endif
--
--struct ieee80211_node *
--#ifdef IEEE80211_DEBUG_REFCNT
- ieee80211_find_node_debug(struct ieee80211_node_table *nt,
- 	const u_int8_t *macaddr, const char *func, int line)
- #else
-@@ -1838,7 +1631,6 @@ ieee80211_node_table_cleanup(struct ieee
- 		ic->ic_node_cleanup(ni);
- #endif
- 	}
--	del_timer(&nt->nt_wds_aging_timer);
- 	IEEE80211_SCAN_LOCK_DESTROY(nt);
- 	IEEE80211_NODE_TABLE_LOCK_DESTROY(nt);
- }
-@@ -2404,8 +2196,6 @@ ieee80211_node_leave(struct ieee80211_no
- 	 * so no more references are generated
- 	 */
- 	if (nt) {
--		ieee80211_remove_wds_addr(nt, ni->ni_macaddr);
--		ieee80211_del_wds_node(nt, ni);
- 		IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
- 		node_table_leave_locked(nt, ni);
- 		IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
---- a/net80211/ieee80211_node.h
-+++ b/net80211/ieee80211_node.h
-@@ -231,13 +231,6 @@ void ieee80211_sta_leave(struct ieee8021
- #define WDS_AGING_STATIC 	0xffff
- #define WDS_AGING_TIMER_VAL 	(WDS_AGING_TIME / 2)
- 
--struct ieee80211_wds_addr {
--	LIST_ENTRY(ieee80211_wds_addr) wds_hash;
--	u_int8_t	wds_macaddr[IEEE80211_ADDR_LEN];
--	struct ieee80211_node *wds_ni;
--	u_int16_t wds_agingcount;
--};
--
- /*
-  * Table of ieee80211_node instances.  Each ieee80211com
-  * has at least one for holding the scan candidates.
-@@ -250,11 +243,9 @@ struct ieee80211_node_table {
- 	ieee80211_node_table_lock_t nt_nodelock;	/* on node table */
- 	TAILQ_HEAD(, ieee80211_node) nt_node;	/* information of all nodes */
- 	ATH_LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE];
--	ATH_LIST_HEAD(, ieee80211_wds_addr) nt_wds_hash[IEEE80211_NODE_HASHSIZE];
- 	ieee80211_scan_lock_t nt_scanlock;	/* on nt_scangen */
- 	u_int nt_scangen;			/* gen# for timeout scan */
- 	int nt_inact_init;			/* initial node inact setting */
--	struct timer_list nt_wds_aging_timer;	/* timer to age out wds entries */
- };
- 
- /* Allocates a new ieee80211_node* that has a reference count of one, and 
-@@ -363,47 +354,6 @@ void
- ieee80211_unref_node(struct ieee80211_node **pni);
- #endif /* #ifdef IEEE80211_DEBUG_REFCNT */
- 
--/* Increments reference count of ieee80211_node *ni */
--#ifdef IEEE80211_DEBUG_REFCNT
--#define ieee80211_add_wds_addr(_table, _node, _mac, _static) \
--	ieee80211_add_wds_addr_debug(_table, _node, _mac, _static, __func__, __LINE__)
--int ieee80211_add_wds_addr_debug(struct ieee80211_node_table *, struct ieee80211_node *,
--	const u_int8_t *, u_int8_t, const char* func, int line);
--#else
--int ieee80211_add_wds_addr(struct ieee80211_node_table *, struct ieee80211_node *,
--	const u_int8_t *, u_int8_t);
--#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
--
--/* Decrements reference count of ieee80211_node *ni */
--#ifdef IEEE80211_DEBUG_REFCNT
--#define ieee80211_remove_wds_addr(_table, _mac) \
--	ieee80211_remove_wds_addr_debug(_table, _mac, __func__, __LINE__)
--void ieee80211_remove_wds_addr_debug(struct ieee80211_node_table *, const u_int8_t *,
--			       const char* func, int line);
--#else
--void ieee80211_remove_wds_addr(struct ieee80211_node_table *, const u_int8_t *);
--#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
--
--/* Decrements reference count of node, if found */
--#ifdef IEEE80211_DEBUG_REFCNT
--#define ieee80211_del_wds_node(_table, _node) \
--	ieee80211_del_wds_node_debug(_table, _node, __func__, __LINE__)
--void ieee80211_del_wds_node_debug(struct ieee80211_node_table *, struct ieee80211_node *,
--			    const char* func, int line);
--#else
--void ieee80211_del_wds_node(struct ieee80211_node_table *, struct ieee80211_node *);
--#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
--
--/* Increments reference count of node, if found */
--#ifdef IEEE80211_DEBUG_REFCNT
--#define ieee80211_find_wds_node(_table, _mac) \
--	ieee80211_find_wds_node_debug(_table, _mac, __func__, __LINE__)
--struct ieee80211_node *ieee80211_find_wds_node_debug(struct ieee80211_node_table *,
--	const u_int8_t *, const char* func, int line);
--#else
--struct ieee80211_node *ieee80211_find_wds_node(struct ieee80211_node_table *,
--	const u_int8_t *);
--#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
- typedef void ieee80211_iter_func(void *, struct ieee80211_node *);
- void ieee80211_iterate_nodes(struct ieee80211_node_table *,
- 	ieee80211_iter_func *, void *);
diff --git a/package/madwifi/patches/393-mbss_vap_auth.patch b/package/madwifi/patches/393-mbss_vap_auth.patch
deleted file mode 100644
index a2637cccbb..0000000000
--- a/package/madwifi/patches/393-mbss_vap_auth.patch
+++ /dev/null
@@ -1,491 +0,0 @@
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -123,6 +123,9 @@ static void ieee80211_node_table_cleanup
- static void ieee80211_node_table_reset(struct ieee80211_node_table *,
- 	struct ieee80211vap *);
- 
-+static struct ieee80211_node *
-+lookup_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap, const u_int8_t *addr);
-+
- MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
- 
- void
-@@ -697,7 +700,7 @@ ieee80211_sta_join(struct ieee80211vap *
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_node *ni;
- 
--	ni = ieee80211_find_node(&ic->ic_sta, se->se_macaddr);
-+	ni = lookup_rxnode(ic, vap, se->se_macaddr);
- 	if (ni == NULL) {
- 		ni = ieee80211_alloc_node_table(vap, se->se_macaddr);
- 		IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
-@@ -1394,6 +1397,53 @@ ieee80211_add_neighbor(struct ieee80211v
- 	return ni;
- }
- 
-+struct ieee80211vap *
-+ieee80211_find_rxvap(struct ieee80211com *ic, const u_int8_t *mac)
-+{
-+	struct ieee80211vap *vap;
-+
-+	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+		if (IEEE80211_ADDR_EQ(vap->iv_myaddr, mac))
-+			return vap;
-+	}
-+	return NULL;
-+}
-+EXPORT_SYMBOL(ieee80211_find_rxvap);
-+
-+static struct ieee80211_node *
-+lookup_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap,
-+	const u_int8_t *addr)
-+{
-+	struct ieee80211_node_table *nt;
-+	struct ieee80211_node *ni = NULL;
-+	int use_bss = 0;
-+	int hash;
-+
-+	nt = &ic->ic_sta;
-+	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
-+	hash = IEEE80211_NODE_HASH(addr);
-+	LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
-+		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, addr)) {
-+			/* allow multiple nodes on different vaps */
-+			if (vap && (ni->ni_vap != vap))
-+				continue;
-+
-+			ieee80211_ref_node(ni);
-+			goto out;
-+		}
-+	}
-+
-+	/* no match found */
-+	ni = NULL;
-+
-+out:
-+	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
-+	return ni;
-+#undef IS_PSPOLL
-+#undef IS_CTL
-+}
-+
-+
- /*
-  * Return the node for the sender of a frame; if the sender is unknown return 
-  * NULL. The caller is expected to deal with this. (The frame is sent to all 
-@@ -1403,10 +1453,10 @@ ieee80211_add_neighbor(struct ieee80211v
-  */
- struct ieee80211_node *
- #ifdef IEEE80211_DEBUG_REFCNT
--ieee80211_find_rxnode_debug(struct ieee80211com *ic,
-+ieee80211_find_rxnode_debug(struct ieee80211com *ic, struct ieee80211vap *vap,
- 	const struct ieee80211_frame_min *wh, const char *func, int line)
- #else
--ieee80211_find_rxnode(struct ieee80211com *ic,
-+ieee80211_find_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap,
- 	const struct ieee80211_frame_min *wh)
- #endif
- {
-@@ -1414,9 +1464,8 @@ ieee80211_find_rxnode(struct ieee80211co
- 	((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
- #define	IS_PSPOLL(wh) \
- 	((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL)
--	struct ieee80211_node_table *nt;
--	struct ieee80211_node *ni;
--	struct ieee80211vap *vap, *avp;
-+	struct ieee80211_node *ni = NULL;
-+	struct ieee80211vap *avp;
- 	const u_int8_t *addr;
- 
- 	if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/)
-@@ -1429,32 +1478,25 @@ ieee80211_find_rxnode(struct ieee80211co
- 
- 	/* XXX check ic_bss first in station mode */
- 	/* XXX 4-address frames? */
--	nt = &ic->ic_sta;
--	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
- 	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) {
--		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+		if (vap) { /* assume unicast if vap is set, mcast not supported for wds */
- 			TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
--				if (!IEEE80211_ADDR_EQ(addr, avp->wds_mac))
-+				if (!IEEE80211_ADDR_EQ(addr, avp->wds_mac) ||
-+					!IEEE80211_ADDR_EQ(wh->i_addr1, avp->iv_myaddr))
- 					continue;
- 
- 				if (avp->iv_wdsnode)
--					return ieee80211_ref_node(avp->iv_wdsnode);
--				else
--					return NULL;
-+					ni = ieee80211_ref_node(avp->iv_wdsnode);
-+				return ni;
- 			}
-+			if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS))
-+				return NULL;
-+		} else {
-+			return NULL;
- 		}
- 	}
- 
--#ifdef IEEE80211_DEBUG_REFCNT
--	ni = ieee80211_find_node_locked_debug(nt, addr, func, line);
--#else
--	ni = ieee80211_find_node_locked(nt, addr);
--#endif
--	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
--
--	return ni;
--#undef IS_PSPOLL
--#undef IS_CTL
-+	return lookup_rxnode(ic, vap, addr);
- }
- #ifdef IEEE80211_DEBUG_REFCNT
- EXPORT_SYMBOL(ieee80211_find_rxnode_debug);
-@@ -1479,15 +1521,14 @@ ieee80211_find_txnode(struct ieee80211va
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_node_table *nt;
- 	struct ieee80211_node *ni = NULL;
-+	int hash;
- 
--	IEEE80211_LOCK_IRQ(ic);
- 	if (vap->iv_opmode == IEEE80211_M_WDS) {
- 		if (vap->iv_wdsnode && (vap->iv_state == IEEE80211_S_RUN))
- 			return ieee80211_ref_node(vap->iv_wdsnode);
- 		else
- 			return NULL;
- 	}
--	IEEE80211_UNLOCK_IRQ(ic);
- 
- 	/*
- 	 * The destination address should be in the node table
-@@ -1505,11 +1546,22 @@ ieee80211_find_txnode(struct ieee80211va
- 	/* XXX: Can't hold lock across dup_bss due to recursive locking. */
- 	nt = &vap->iv_ic->ic_sta;
- 	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
-+	hash = IEEE80211_NODE_HASH(mac);
-+	LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
-+		if (ni->ni_vap != vap)
-+			continue;
-+
-+		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, mac)) {
- #ifdef IEEE80211_DEBUG_REFCNT
--	ni = ieee80211_find_node_locked_debug(nt, mac, func, line);
-+			ieee80211_ref_node_debug(ni, func, line);
- #else
--	ni = ieee80211_find_node_locked(nt, mac);
-+			ieee80211_ref_node(ni);
- #endif
-+			goto found;
-+		}
-+	}
-+	ni = NULL;
-+found:
- 	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
- 
- 	if (ni == NULL) {
-@@ -1964,13 +2016,32 @@ remove_worse_nodes(void *arg, struct iee
- 		}
- }
- 
-+static void
-+remove_duplicate_nodes(void *arg, struct ieee80211_node *ni)
-+{
-+	struct ieee80211_node *rni = arg;
-+
-+	if (ni == rni)
-+		return;
-+
-+	if (ni->ni_vap == rni->ni_vap)
-+		return;
-+
-+	if (!IEEE80211_ADDR_EQ(rni->ni_macaddr, ni->ni_macaddr))
-+		return;
-+
-+	ieee80211_node_leave(ni);
-+}
-+
- void
- ieee80211_node_join(struct ieee80211_node *ni, int resp)
- {
- 	struct ieee80211com *ic = ni->ni_ic;
- 	struct ieee80211vap *vap = ni->ni_vap;
-+	struct ieee80211_node *tni;
- 	int newassoc;
- 
-+	ieee80211_iterate_nodes(&ic->ic_sta, remove_duplicate_nodes, ni);
- 	if (ni->ni_associd == 0) {
- 		u_int16_t aid;
- 
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -216,16 +216,14 @@ ieee80211_input(struct ieee80211vap * va
- 
- 	type = -1;			/* undefined */
- 
--	if (!vap)
--		goto out;
-+	if (!vap || !vap->iv_bss || !vap->iv_dev || !vap->iv_ic)
-+		goto discard;
- 
- 	ic = vap->iv_ic;
--	if (!ic)
--		goto out;
--
- 	dev = vap->iv_dev;
--	if (!dev)
--		goto out;
-+
-+	if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
-+		goto discard;
- 
- 	/* initialize ni as in the previous API */
- 	if (ni_or_null == NULL) {
-@@ -233,9 +231,10 @@ ieee80211_input(struct ieee80211vap * va
-                 * guarantee its existence during the following call, hence
-                 * briefly grab our own reference. */
- 		ni = ieee80211_ref_node(vap->iv_bss);
-+		KASSERT(ni != NULL, ("null node"));
-+	} else {
-+		ni->ni_inact = ni->ni_inact_reload;
- 	}
--	KASSERT(ni != NULL, ("null node"));
--	ni->ni_inact = ni->ni_inact_reload;
- 
- 	KASSERT(skb->len >= sizeof(struct ieee80211_frame_min),
- 		("frame length too short: %u", skb->len));
-@@ -844,10 +843,11 @@ ieee80211_input(struct ieee80211vap * va
- err:
- 	vap->iv_devstats.rx_errors++;
- out:
--	if (skb != NULL)
--		ieee80211_dev_kfree_skb(&skb);
- 	if (ni_or_null == NULL)
- 		ieee80211_unref_node(&ni);
-+discard:
-+	if (skb != NULL)
-+		ieee80211_dev_kfree_skb(&skb);
- 	return type;
- #undef HAS_SEQ
- }
-@@ -929,16 +929,23 @@ int
- ieee80211_input_all(struct ieee80211com *ic,
- 	struct sk_buff *skb, int rssi, u_int64_t rtsf)
- {
-+	struct ieee80211_frame_min *wh = (struct ieee80211_frame_min *) skb->data;
- 	struct ieee80211vap *vap;
- 	int type = -1;
- 
- 	/* XXX locking */
- 	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+		struct ieee80211_node *ni = NULL;
- 		struct sk_buff *skb1;
- 
- 		if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
- 			continue;
- 
-+		if ((vap->iv_opmode == IEEE80211_M_HOSTAP) &&
-+			!IEEE80211_IS_MULTICAST(wh->i_addr1))
-+			continue;
-+
-+		ni = ieee80211_find_rxnode(ic, vap, wh);
- 		if (TAILQ_NEXT(vap, iv_next) != NULL) {
- 			skb1 = skb_copy(skb, GFP_ATOMIC);
- 			if (skb1 == NULL) {
-@@ -950,8 +957,12 @@ ieee80211_input_all(struct ieee80211com
- 			skb1 = skb;
- 			skb = NULL;
- 		}
--		type = ieee80211_input(vap, NULL, skb1, rssi, rtsf);
-+		type = ieee80211_input(vap, ni, skb1, rssi, rtsf);
-+		if (ni)
-+			ieee80211_unref_node(&ni);
- 	}
-+
-+out:
- 	if (skb != NULL)		/* no vaps, reclaim skb */
- 		ieee80211_dev_kfree_skb(&skb);
- 	return type;
-@@ -1147,11 +1158,9 @@ ieee80211_deliver_data(struct ieee80211_
- 			 * sending it will not work; just let it be
- 			 * delivered normally.
- 			 */
--			struct ieee80211_node *ni1 = ieee80211_find_node(
--				&vap->iv_ic->ic_sta, eh->ether_dhost);
-+			struct ieee80211_node *ni1 = ieee80211_find_txnode(vap, eh->ether_dhost);
- 			if (ni1 != NULL) {
--				if (ni1->ni_vap == vap &&
--				    ieee80211_node_is_authorized(ni1) &&
-+				if (ieee80211_node_is_authorized(ni1) &&
- 					!ni1->ni_subif &&
- 				    ni1 != vap->iv_bss) {
- 
-@@ -3520,6 +3529,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 				 (vap->iv_opmode == IEEE80211_M_WDS)) &&
- 				(scan.capinfo & IEEE80211_CAPINFO_ESS))) {
- 			struct ieee80211vap *avp = NULL;
-+			int do_unref = 0;
- 			int found = 0;
- 
- 			IEEE80211_LOCK_IRQ(vap->iv_ic);
-@@ -3553,10 +3563,12 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 					ni->ni_associd |= 0xc000;
- 					avp->iv_wdsnode = ieee80211_ref_node(ni);
- 					IEEE80211_UNLOCK_IRQ(ic);
--				} else if (vap->iv_opmode == IEEE80211_M_IBSS) {
-+				} else if ((vap->iv_opmode == IEEE80211_M_IBSS) &&
-+				           IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid)) {
- 					/* Create a new entry in the neighbor table. */
- 					ni = ieee80211_add_neighbor(vap, wh, &scan);
- 				}
-+				do_unref = 1;
- 			} else {
- 				/*
- 				 * Copy data from beacon to neighbor table.
-@@ -3595,6 +3607,8 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 				ni->ni_rssi = rssi;
- 				ni->ni_rtsf = rtsf;
- 				ni->ni_last_rx = jiffies;
-+				if (do_unref)
-+					ieee80211_unref_node(&ni);
- 			}
- 		}
- 		break;
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -6589,9 +6589,8 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 
- 	sc->sc_recv_mgmt(vap, ni_or_null, skb, subtype, rssi, rtsf);
- 
--
- 	/* Lookup the new node if any (this grabs a reference to it) */
--	ni = ieee80211_find_rxnode(vap->iv_ic,
-+	ni = ieee80211_find_rxnode(vap->iv_ic, vap,
- 	         (const struct ieee80211_frame_min *)skb->data);
- 	if (ni == NULL) {
- 		DPRINTF(sc, ATH_DEBUG_BEACON, "Dropping; node unknown.\n");
-@@ -6746,7 +6745,9 @@ ath_rx_poll(struct net_device *dev, int
- 	struct ath_desc *ds;
- 	struct ath_rx_status *rs;
- 	struct sk_buff *skb = NULL;
-+	struct ieee80211vap *vap;
- 	struct ieee80211_node *ni;
-+	const struct ieee80211_frame_min *wh;
- 	unsigned int len;
- 	int type;
- 	u_int phyerr;
-@@ -6901,12 +6902,15 @@ rx_accept:
- 		skb_trim(skb, skb->len - IEEE80211_CRC_LEN);
- 
- 		if (mic_fail) {
-+			wh = (const struct ieee80211_frame_min *) skb->data;
-+
- 			/* Ignore control frames which are reported with mic error */
--		    if ((((struct ieee80211_frame *)skb->data)->i_fc[0] &
-+		    if ((wh->i_fc[0] &
- 					IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
- 				goto drop_micfail;
- 
--			ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
-+			vap = ieee80211_find_rxvap(ic, wh->i_addr1);
-+			ni = ieee80211_find_rxnode(ic, vap, wh);
- 
- 			if (ni && ni->ni_table) {
- 				ieee80211_check_mic(ni, skb);
-@@ -6968,11 +6972,24 @@ drop_micfail:
- 		 * for its use.  If the sender is unknown spam the
- 		 * frame; it'll be dropped where it's not wanted.
- 		 */
--		if (rs->rs_keyix != HAL_RXKEYIX_INVALID &&
-+		wh = (const struct ieee80211_frame_min *) skb->data;
-+		if ((rs->rs_keyix != HAL_RXKEYIX_INVALID) &&
- 		    (ni = sc->sc_keyixmap[rs->rs_keyix]) != NULL) {
- 			/* Fast path: node is present in the key map;
- 			 * grab a reference for processing the frame. */
--			ni = ieee80211_ref_node(ni);
-+			ieee80211_ref_node(ni);
-+			if ((ATH_GET_VAP_ID(wh->i_addr1) !=
-+			     ATH_GET_VAP_ID(ni->ni_vap->iv_myaddr)) ||
-+				((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) ==
-+				 IEEE80211_FC1_DIR_DSTODS)) {
-+				/* key cache node lookup is fast, but it can
-+				 * lead to problems in multi-bss (foreign vap
-+				 * node reference) or wds (wdsap node ref instead
-+				 * of base ap node ref).
-+				 * use slowpath lookup in both cases
-+				 */
-+				goto lookup_slowpath;
-+			}
- 			ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
- 			type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
- 			ieee80211_unref_node(&ni);
-@@ -6981,24 +6998,39 @@ drop_micfail:
- 			 * No key index or no entry, do a lookup and
- 			 * add the node to the mapping table if possible.
- 			 */
--			ni = ieee80211_find_rxnode(ic,
--				(const struct ieee80211_frame_min *)skb->data);
-+
-+lookup_slowpath:
-+			if (IEEE80211_IS_MULTICAST(wh->i_addr1))
-+				vap = NULL;
-+			else
-+				vap = ieee80211_find_rxvap(ic, wh->i_addr1);
-+
-+			if (vap)
-+				ni = ieee80211_find_rxnode(ic, vap, wh);
-+			else
-+				ni = NULL;
-+
- 			if (ni != NULL) {
- 				ieee80211_keyix_t keyix;
- 
- 				ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
--				type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
-+				type = ieee80211_input(vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
- 				/*
- 				 * If the station has a key cache slot assigned
- 				 * update the key->node mapping table.
- 				 */
- 				keyix = ni->ni_ucastkey.wk_keyix;
- 				if (keyix != IEEE80211_KEYIX_NONE &&
--				    sc->sc_keyixmap[keyix] == NULL)
-+				    sc->sc_keyixmap[keyix] == NULL) {
- 					sc->sc_keyixmap[keyix] = ieee80211_ref_node(ni);
-+				}
- 				ieee80211_unref_node(&ni);
--			} else
--				type = ieee80211_input_all(ic, skb, rs->rs_rssi, bf->bf_tsf);
-+			} else {
-+				if (vap)
-+					type = ieee80211_input(vap, NULL, skb, rs->rs_rssi, bf->bf_tsf);
-+				else
-+					type = ieee80211_input_all(ic, skb, rs->rs_rssi, bf->bf_tsf);
-+			}
- 		}
- 
- 		if (sc->sc_diversity) {
---- a/net80211/ieee80211_node.h
-+++ b/net80211/ieee80211_node.h
-@@ -286,15 +286,18 @@ struct ieee80211_node *ieee80211_find_no
- 	const u_int8_t *);
- #endif /* #ifdef IEEE80211_DEBUG_REFCNT */
- 
-+struct ieee80211vap *
-+ieee80211_find_rxvap(struct ieee80211com *ic, const u_int8_t *mac);
-+
- /* Returns a ieee80211_node* with refcount incremented, if found */
- #ifdef IEEE80211_DEBUG_REFCNT
--#define	ieee80211_find_rxnode(_nt, _wh) \
--	ieee80211_find_rxnode_debug(_nt, _wh, __func__, __LINE__)
-+#define	ieee80211_find_rxnode(_nt, _vap, _wh) \
-+	ieee80211_find_rxnode_debug(_nt, _vap, _wh, __func__, __LINE__)
- struct ieee80211_node *ieee80211_find_rxnode_debug(struct ieee80211com *,
--	const struct ieee80211_frame_min *, const char *, int);
-+	struct ieee80211vap *, const struct ieee80211_frame_min *, const char *, int);
- #else
- struct ieee80211_node *ieee80211_find_rxnode(struct ieee80211com *,
--	const struct ieee80211_frame_min *);
-+	struct ieee80211vap *, const struct ieee80211_frame_min *);
- #endif /* #ifdef IEEE80211_DEBUG_REFCNT */
- 
- /* Returns a ieee80211_node* with refcount incremented, if found */
diff --git a/package/madwifi/patches/394-probereq.patch b/package/madwifi/patches/394-probereq.patch
deleted file mode 100644
index 706d5a5ac3..0000000000
--- a/package/madwifi/patches/394-probereq.patch
+++ /dev/null
@@ -1,64 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -3621,6 +3621,8 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			vap->iv_stats.is_rx_mgtdiscard++;
- 			return;
- 		}
-+		if (vap->iv_no_probereq)
-+			return;
- 		if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
- 			/* frame must be directed */
- 			vap->iv_stats.is_rx_mgtdiscard++;	/* XXX: stat */
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -651,6 +651,7 @@ enum {
- 	IEEE80211_PARAM_RSSI_DIS_COUNT	= 81,	/* counter for rssi threshold */
- 	IEEE80211_PARAM_WDS_SEP			= 82,	/* move wds stations into separate interfaces */
- 	IEEE80211_PARAM_MAXASSOC		= 83,	/* maximum associated stations */
-+	IEEE80211_PARAM_PROBEREQ		= 84,	/* enable handling of probe requests */
- };
- 
- #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -198,6 +198,7 @@ struct ieee80211vap {
- 	u_int32_t iv_debug;				/* debug msg flags */
- 	struct ieee80211_stats iv_stats;		/* statistics */
- 
-+	int iv_no_probereq;
- 	int iv_max_nodes;
- 	int iv_monitor_nods_only;			/* in monitor mode only nods traffic */
- 	int iv_monitor_txf_len;				/* in monitor mode, truncate tx packets */
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2881,6 +2881,9 @@ ieee80211_ioctl_setparam(struct net_devi
- 		else
- 			vap->iv_max_nodes = value;
- 		break;
-+	case IEEE80211_PARAM_PROBEREQ:
-+		vap->iv_no_probereq = !value;
-+		break;
- #ifdef ATH_REVERSE_ENGINEERING
- 	case IEEE80211_PARAM_DUMPREGS:
- 		ieee80211_dump_registers(dev, info, w, extra);
-@@ -3243,6 +3246,9 @@ ieee80211_ioctl_getparam(struct net_devi
- 	case IEEE80211_PARAM_MAXASSOC:
- 		param[0] = vap->iv_max_nodes;
- 		break;
-+	case IEEE80211_PARAM_PROBEREQ:
-+		param[0] = !vap->iv_no_probereq;
-+		break;
- 	default:
- 		return -EOPNOTSUPP;
- 	}
-@@ -5802,6 +5808,10 @@ static const struct iw_priv_args ieee802
- 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxassoc"},
- 	{ IEEE80211_PARAM_MAXASSOC,
- 	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxassoc"},
-+	{ IEEE80211_PARAM_PROBEREQ,
-+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "probereq"},
-+	{ IEEE80211_PARAM_PROBEREQ,
-+	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_probereq"},
- 
- #ifdef ATH_REVERSE_ENGINEERING
- 	/*
diff --git a/package/madwifi/patches/395-ath_ff_unmap.patch b/package/madwifi/patches/395-ath_ff_unmap.patch
deleted file mode 100644
index 85ddc7bd9f..0000000000
--- a/package/madwifi/patches/395-ath_ff_unmap.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -13534,7 +13534,7 @@ cleanup_ath_buf(struct ath_softc *sc, st
- 				bus_unmap_single(
- 					sc->sc_bdev,
- 					bf->bf_skbaddrff[i], 
--					(direction == BUS_DMA_TODEVICE ? 
-+					(direction == BUS_DMA_FROMDEVICE ? 
- 					 sc->sc_rxbufsize : ffskb->len), 
- 					direction);
- 				bf->bf_skbaddrff[i] = 0;
diff --git a/package/madwifi/patches/396-napi_ff_fix.patch b/package/madwifi/patches/396-napi_ff_fix.patch
deleted file mode 100644
index ca35d4ccac..0000000000
--- a/package/madwifi/patches/396-napi_ff_fix.patch
+++ /dev/null
@@ -1,65 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -6734,10 +6734,10 @@ ath_rx_poll(struct net_device *dev, int
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
- 	struct ath_softc *sc = container_of(napi, struct ath_softc, sc_napi);
- 	struct net_device *dev = sc->sc_dev;
--	u_int rx_limit = budget;
-+	int rx_limit = budget;
- #else
- 	struct ath_softc *sc = dev->priv;
--	u_int rx_limit = min(dev->quota, *budget);
-+	int rx_limit = min(dev->quota, *budget);
- #endif
- 	struct ath_buf *bf;
- 	struct ieee80211com *ic = &sc->sc_ic;
-@@ -6780,13 +6780,15 @@ process_rx_again:
- 			break;
- 		}
- 
--		if (rx_limit-- < 2) {
-+		processed += ic->ic_recv;
-+		rx_limit -= ic->ic_recv;
-+		ic->ic_recv = 0;
-+
-+		/* keep a reserve for napi */
-+		if (rx_limit < 4) {
- 			early_stop = 1;
- 			break;
- 		}
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
--		processed++;
--#endif
- 
- 		skb = bf->bf_skb;
- 		if (skb == NULL) {
-@@ -7074,8 +7076,8 @@ rx_next:
- 		if (sc->sc_isr & HAL_INT_RX) {
- 			u_int64_t hw_tsf = ath_hal_gettsf64(ah);
- 			sc->sc_isr &= ~HAL_INT_RX;
--			local_irq_restore(flags);
- 			ath_uapsd_processtriggers(sc, hw_tsf);
-+			local_irq_restore(flags);
- 			goto process_rx_again;
- 		}
- 		local_irq_restore(flags);
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -1206,6 +1206,7 @@ ieee80211_deliver_data(struct ieee80211_
- 		}
- 	}
- 
-+	vap->iv_ic->ic_recv++;
- 	if (skb != NULL) {
- 		skb->dev = dev;
- 
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -323,6 +323,7 @@ struct ieee80211com {
- 	struct ifmedia ic_media;		/* interface media config */
- 	u_int8_t ic_myaddr[IEEE80211_ADDR_LEN];
- 	struct timer_list ic_inact;		/* mgmt/inactivity timer */
-+	u_int ic_recv;					/* frame received counter */
- 
- 	unsigned int ic_subifs;
- 	u_int32_t ic_flags;			/* state flags */
diff --git a/package/madwifi/patches/400-new_hal.patch b/package/madwifi/patches/400-new_hal.patch
deleted file mode 100644
index 12a59687be..0000000000
--- a/package/madwifi/patches/400-new_hal.patch
+++ /dev/null
@@ -1,153 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -606,6 +606,14 @@ ath_attach(u_int16_t devid, struct net_d
- 	}
- 	sc->sc_ah = ah;
- 
-+	/* WAR for AR7100 PCI bug */
-+#if defined(CONFIG_ATHEROS_AR71XX) || defined(CONFIG_ATH79)
-+	if ((ar_device(sc->devid) >= 5210) && (ar_device(sc->devid) < 5416)) {
-+		ath_hal_setcapability(ah, HAL_CAP_DMABURST_RX, 0, HAL_DMABURST_4B, NULL);
-+		ath_hal_setcapability(ah, HAL_CAP_DMABURST_TX, 0, HAL_DMABURST_4B, NULL);
-+	}
-+#endif
-+
- 	/*
- 	 * Check if the MAC has multi-rate retry support.
- 	 * We do this by trying to setup a fake extended
-@@ -7568,7 +7576,7 @@ ath_txq_setup(struct ath_softc *sc, int
- 	if (qtype == HAL_TX_QUEUE_UAPSD)
- 		qi.tqi_qflags = HAL_TXQ_TXDESCINT_ENABLE;
- 	else
--		qi.tqi_qflags = HAL_TXQ_TXEOLINT_ENABLE | 
-+		qi.tqi_qflags = HAL_TXQ_TXEOLINT_ENABLE | HAL_TXQ_TXOKINT_ENABLE |
- 			HAL_TXQ_TXDESCINT_ENABLE;
- 	qnum = ath_hal_setuptxqueue(ah, qtype, &qi);
- 	if (qnum == -1) {
---- a/ath_hal/ah_os.c
-+++ b/ath_hal/ah_os.c
-@@ -126,6 +126,13 @@ ath_hal_printf(struct ath_hal *ah, const
- }
- EXPORT_SYMBOL(ath_hal_printf);
- 
-+void __ahdecl
-+ath_hal_printstr(struct ath_hal *ah, const char *str)
-+{
-+	printk("%s", str);
-+}
-+EXPORT_SYMBOL(ath_hal_printstr);
-+
- /*
-  * Format an Ethernet MAC for printing.
-  */
---- a/ath_hal/ah_os.h
-+++ b/ath_hal/ah_os.h
-@@ -156,69 +156,23 @@ extern u_int32_t __ahdecl ath_hal_getupt
- #endif
- #endif				/* AH_BYTE_ORDER */
- 
--/*
-- * Some big-endian architectures don't set CONFIG_GENERIC_IOMAP, but fail to
-- * implement iowrite32be and ioread32be.  Provide compatibility macros when
-- * it's needed.
-- *
-- * As of Linux 2.6.24, only MIPS, PARISC and PowerPC implement iowrite32be and
-- * ioread32be as functions.
-- *
-- * The downside or the replacement macros it that we may be byte-swapping data
-- * for the second time, so the native implementations should be preferred.
-- */
--#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) && \
--	!defined(CONFIG_GENERIC_IOMAP) && (AH_BYTE_ORDER == AH_BIG_ENDIAN) && \
--	!defined(__mips__) && !defined(__hppa__) && !defined(__powerpc__)
--# ifndef iowrite32be
--#  define iowrite32be(_val, _addr) iowrite32(swab32((_val)), (_addr))
--# endif
--# ifndef ioread32be
--#  define ioread32be(_addr) swab32(ioread32((_addr)))
--# endif
--#endif
-+#define IS_SWAPPED(_ah, _reg) \
-+	((_ah)->ah_swapped && \
-+		(((0x4000 <= (_reg)) && ((_reg) < 0x5000)) || \
-+		 ((0x7000 <= (_reg)) && ((_reg) < 0x8000))))
-+
-+#define SWAPREG(_ah, _reg, _val) \
-+	(IS_SWAPPED(_ah, _reg) ? cpu_to_le32(_val) : (_val))
- 
- /*
-  * The register accesses are done using target-specific functions when
-  * debugging is enabled (AH_DEBUG) or it's explicitly requested for the target.
-- *
-- * The hardware registers use little-endian byte order natively.  Big-endian
-- * systems are configured by HAL to enable hardware byte-swap of register reads
-- * and writes at reset.  This avoid the need to byte-swap the data in software.
-- * However, the registers in a certain area from 0x4000 to 0x4fff (PCI clock
-- * domain registers) are not byte swapped!
-- *
-- * Since Linux I/O primitives default to little-endian operations, we only
-- * need to suppress byte-swapping on big-endian systems outside the area used
-- * by the PCI clock domain registers.
-  */
--#if (AH_BYTE_ORDER == AH_BIG_ENDIAN)
--#define is_reg_le(__reg) ((0x4000 <= (__reg) && (__reg) < 0x5000))
--#else
--#define is_reg_le(__reg) 1
--#endif
--
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
--#define _OS_REG_WRITE(_ah, _reg, _val) do {			\
--	 is_reg_le(_reg) ?					\
--	 iowrite32((_val), (_ah)->ah_sh + (_reg)) :		\
--	 iowrite32be((_val), (_ah)->ah_sh + (_reg));		\
--	} while (0)
--#define _OS_REG_READ(_ah, _reg)					\
--	(is_reg_le(_reg) ?					\
--	 ioread32((_ah)->ah_sh + (_reg)) :			\
--	 ioread32be((_ah)->ah_sh + (_reg)))
--#else
- #define _OS_REG_WRITE(_ah, _reg, _val) do {			\
--	 writel(is_reg_le(_reg) ? 				\
--	 	(_val) : cpu_to_le32(_val), 			\
--		(_ah)->ah_sh + (_reg));				\
--	} while (0)
-+	 __raw_writel(SWAPREG(_ah, _reg, _val), (_ah)->ah_sh + (_reg));		\
-+} while (0)
- #define _OS_REG_READ(_ah, _reg)					\
--	(is_reg_le(_reg) ?					\
--	 readl((_ah)->ah_sh + (_reg)) :				\
--	 cpu_to_le32(readl((_ah)->ah_sh + (_reg))))
--#endif				/* KERNEL_VERSION(2,6,12) */
-+	 SWAPREG(_ah, _reg, __raw_readl((_ah)->ah_sh + (_reg)))
- 
- /*
-  * The functions in this section are not intended to be invoked by MadWifi
---- a/ath/if_ath_hal.h
-+++ b/ath/if_ath_hal.h
-@@ -778,17 +778,6 @@ static inline HAL_STATUS ath_hal_getcapa
- 	return ret;
- }
- 
--static inline HAL_BOOL ath_hal_radar_wait(struct ath_hal *ah, HAL_CHANNEL *a1)
--{
--	HAL_BOOL ret;
--	ATH_HAL_LOCK_IRQ(ah->ah_sc);
--	ath_hal_set_function(__func__);
--	ret = ah->ah_radarWait(ah, a1);
--	ath_hal_set_function(NULL);
--	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
--	return ret;
--}
--
- static inline HAL_BOOL ath_hal_setmcastfilterindex(struct ath_hal *ah,
- 						   u_int32_t index)
- {
-@@ -1268,8 +1257,6 @@ static inline void ath_hal_dump_map(stru
- 	/* HAL_STATUS ah_getCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE a1, u_int32_t capability, u_int32_t *result) */
- 	__print_symbol("%s=ah_getCapability\n",
- 		       (unsigned long)ah->ah_getCapability);
--	/* HAL_BOOL ah_radarWait(struct ath_hal *ah, HAL_CHANNEL *a1) */
--	__print_symbol("%s=ah_radarWait\n", (unsigned long)ah->ah_radarWait);
- 	/* HAL_BOOL ah_setMulticastFilterIndex(struct ath_hal *ah, u_int32_t index) */
- 	__print_symbol("%s=ah_setMulticastFilterIndex\n",
- 		       (unsigned long)ah->ah_setMulticastFilterIndex);
diff --git a/package/madwifi/patches/401-changeset_r3602.patch b/package/madwifi/patches/401-changeset_r3602.patch
deleted file mode 100644
index cf9c879666..0000000000
--- a/package/madwifi/patches/401-changeset_r3602.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -348,6 +348,8 @@ typedef spinlock_t acl_lock_t;
- /* __skb_append got a third parameter in 2.6.14 */
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
- #define __skb_append(a,b,c)	__skb_append(a, b)
-+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
-+#define __skb_append(a,b,c)	__skb_queue_after(c, a, b)
- #endif
- 
- /*
diff --git a/package/madwifi/patches/402-changeset_r3603.patch b/package/madwifi/patches/402-changeset_r3603.patch
deleted file mode 100644
index 92f6e6ea44..0000000000
--- a/package/madwifi/patches/402-changeset_r3603.patch
+++ /dev/null
@@ -1,176 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -40,10 +40,7 @@
- # Makefile for the HAL-based Atheros driver.
- #
- 
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)
- 
- ifneq (svnversion.h,$(MAKECMDGOALS))
---- a/ath/Makefile
-+++ b/ath/Makefile
-@@ -40,10 +40,7 @@
- # Makefile for the Atheros WLAN driver.
- #
- 
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/..
- 
- ifeq ($(strip $(BUS)),AHB)
---- a/ath_hal/Makefile
-+++ b/ath_hal/Makefile
-@@ -40,10 +40,7 @@
- # Makefile for the Atheros WLAN driver.
- #
- 
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/..
- 
- include $(TOP)/Makefile.inc
---- a/ath_rate/Makefile
-+++ b/ath_rate/Makefile
-@@ -1,7 +1,4 @@
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/..
- 
- obj-y := amrr/ onoe/ sample/ minstrel/
---- a/ath_rate/amrr/Makefile
-+++ b/ath_rate/amrr/Makefile
-@@ -40,10 +40,7 @@
- #
- # Makefile for the Atheros Rate Control Support.
- #
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/../..
- 
- obj-m		+= ath_rate_amrr.o
---- a/ath_rate/minstrel/Makefile
-+++ b/ath_rate/minstrel/Makefile
-@@ -38,10 +38,7 @@
- #
- # Makefile for the Atheros Rate Control Support.
- #
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/../..
- 
- obj-m		+= ath_rate_minstrel.o
---- a/ath_rate/onoe/Makefile
-+++ b/ath_rate/onoe/Makefile
-@@ -40,10 +40,7 @@
- #
- # Makefile for the Atheros Rate Control Support.
- #
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/../..
- 
- obj-m		+= ath_rate_onoe.o
---- a/ath_rate/sample/Makefile
-+++ b/ath_rate/sample/Makefile
-@@ -38,10 +38,7 @@
- #
- # Makefile for the Atheros Rate Control Support.
- #
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/../..
- 
- obj-m		+= ath_rate_sample.o
---- a/net80211/Makefile
-+++ b/net80211/Makefile
-@@ -39,10 +39,7 @@
- #
- # Makefile for the 802.11 WLAN modules.
- #
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/..
- #
- # There is one authenticator mechanism: an in-kernel implementation
---- a/regression/Makefile
-+++ b/regression/Makefile
-@@ -1,7 +1,4 @@
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/..
- 
- obj-y := ccmp/ tkip/ wep/
---- a/regression/ccmp/Makefile
-+++ b/regression/ccmp/Makefile
-@@ -1,10 +1,7 @@
- #
- # Makefile for the CCMP regression test.
- #
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/../..
- 
- obj-m			+= ath_test_ccmp.o
---- a/regression/tkip/Makefile
-+++ b/regression/tkip/Makefile
-@@ -1,10 +1,7 @@
- #
- # Makefile for the TKIP regression test.
- #
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/../..
- 
- obj-m			+= ath_test_tkip.o
---- a/regression/wep/Makefile
-+++ b/regression/wep/Makefile
-@@ -1,10 +1,7 @@
- #
- # Makefile for the WEP regression test.
- #
--ifeq ($(obj),)
--obj=	.
--endif
--
-+obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/../..
- 
- obj-m			+= ath_test_wep.o
diff --git a/package/madwifi/patches/403-changeset_r3605.patch b/package/madwifi/patches/403-changeset_r3605.patch
deleted file mode 100644
index 57ce521c14..0000000000
--- a/package/madwifi/patches/403-changeset_r3605.patch
+++ /dev/null
@@ -1,70 +0,0 @@
---- a/include/compat.h
-+++ b/include/compat.h
-@@ -182,6 +182,13 @@ static inline int timeval_compare(struct
- #define DEV_ATH CTL_UNNUMBERED
- #endif
- 
-+/* __skb_append got a third parameter in 2.6.14 */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
-+#define __skb_queue_after(_list, _old, _new)	__skb_append(_old, _new)
-+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
-+#define __skb_queue_after(_list, _old, _new)	__skb_append(_old, _new, _list)
-+#endif
-+
- #endif /* __KERNEL__ */
- 
- #endif /* _ATH_COMPAT_H_ */
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -345,13 +345,6 @@ typedef spinlock_t acl_lock_t;
- #define	ACL_LOCK_CHECK(_as)
- #endif
- 
--/* __skb_append got a third parameter in 2.6.14 */
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
--#define __skb_append(a,b,c)	__skb_append(a, b)
--#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
--#define __skb_append(a,b,c)	__skb_queue_after(c, a, b)
--#endif
--
- /*
-  * Per-node power-save queue definitions.  Beware of control
-  * flow with IEEE80211_NODE_SAVEQ_LOCK/IEEE80211_NODE_SAVEQ_UNLOCK.
-@@ -395,16 +388,16 @@ typedef spinlock_t acl_lock_t;
- 	_skb = __skb_dequeue(&(_ni)->ni_savedq);		\
- 	(_qlen) = skb_queue_len(&(_ni)->ni_savedq);		\
- } while (0)
--#define	_IEEE80211_NODE_SAVEQ_ENQUEUE(_ni, _skb, _qlen, _age) do {\
--	struct sk_buff *tail = skb_peek_tail(&(_ni)->ni_savedq);\
--	if (tail != NULL) {					\
--		_age -= M_AGE_GET(tail);			\
--		__skb_append(tail, _skb, &(_ni)->ni_savedq);	\
--	} else { 						\
--		__skb_queue_head(&(_ni)->ni_savedq, _skb);	\
--	}							\
--	M_AGE_SET(_skb, _age);					\
--	(_qlen) = skb_queue_len(&(_ni)->ni_savedq); 		\
-+#define	_IEEE80211_NODE_SAVEQ_ENQUEUE(_ni, _skb, _qlen, _age) do {	\
-+	struct sk_buff *tail = skb_peek_tail(&(_ni)->ni_savedq);	\
-+	if (tail != NULL) {						\
-+		_age -= M_AGE_GET(tail);				\
-+		__skb_queue_after(&(_ni)->ni_savedq, tail, _skb);	\
-+	} else { 							\
-+		__skb_queue_head(&(_ni)->ni_savedq, _skb);		\
-+	}								\
-+	M_AGE_SET(_skb, _age);						\
-+	(_qlen) = skb_queue_len(&(_ni)->ni_savedq); 			\
- } while (0)
- 
- /*
---- a/net80211/ieee80211_power.c
-+++ b/net80211/ieee80211_power.c
-@@ -243,7 +243,7 @@ ieee80211_pwrsave(struct sk_buff *skb)
- 	tail = skb_peek_tail(&ni->ni_savedq);
- 	if (tail != NULL) {
- 		age -= M_AGE_GET(tail);
--		__skb_append(tail, skb, &ni->ni_savedq);
-+		__skb_queue_after(&ni->ni_savedq, tail, skb);
- 	} else
- 		__skb_queue_head(&ni->ni_savedq, skb);
- 	M_AGE_SET(skb, age);
diff --git a/package/madwifi/patches/404-linux24_fix.patch b/package/madwifi/patches/404-linux24_fix.patch
deleted file mode 100644
index 4ea20b3cb7..0000000000
--- a/package/madwifi/patches/404-linux24_fix.patch
+++ /dev/null
@@ -1,15 +0,0 @@
---- a/ath_hal/Makefile
-+++ b/ath_hal/Makefile
-@@ -78,10 +78,11 @@ endif
- quiet_cmd_uudecode = UUDECODE $@
-       cmd_uudecode = $(obj)/uudecode -o $@ $<
- 
--$(obj)/$(TARGET).hal.o: $(HAL)/public/$(TARGET).hal.o.uu $(obj)/uudecode
- ifdef LINUX24
-+$(TARGET).hal.o: $(HAL)/public/$(TARGET).hal.o.uu $(obj)/uudecode
- 	$(Q)$(obj)/uudecode -o $@ $<
- else
-+$(obj)/$(TARGET).hal.o: $(HAL)/public/$(TARGET).hal.o.uu $(obj)/uudecode
- 	$(call if_changed,uudecode)
- endif
- 
diff --git a/package/madwifi/patches/405-retransmit_check.patch b/package/madwifi/patches/405-retransmit_check.patch
deleted file mode 100644
index 11e78aba87..0000000000
--- a/package/madwifi/patches/405-retransmit_check.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/net80211/ieee80211.h
-+++ b/net80211/ieee80211.h
-@@ -174,8 +174,6 @@ struct ieee80211_ctlframe_addr2 {
- #define	IEEE80211_SEQ_SEQ_MASK			0xfff0
- #define	IEEE80211_SEQ_SEQ_SHIFT			4
- 
--#define	IEEE80211_SEQ_LEQ(a,b)	((int)((a)-(b)) <= 0)
--
- #define	IEEE80211_NWID_LEN			32
- 
- #define	IEEE80211_QOS_TXOP			0x00ff
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -428,7 +428,7 @@ ieee80211_input(struct ieee80211vap * va
- 				tid = 0;
- 			rxseq = le16toh(*(__le16 *)wh->i_seq);
- 			if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
--			    IEEE80211_SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
-+			    (rxseq == ni->ni_rxseqs[tid])) {
- 				/* duplicate, discard */
- 				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
- 					bssid, "duplicate",
diff --git a/package/madwifi/patches/406-monitor_r3711.patch b/package/madwifi/patches/406-monitor_r3711.patch
deleted file mode 100644
index 4e2c6aefb7..0000000000
--- a/package/madwifi/patches/406-monitor_r3711.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -6530,7 +6530,7 @@ ath_capture(struct net_device *dev, cons
- 
- 	/* Never copy the SKB, as it is ours on the RX side, and this is the 
- 	 * last process on the TX side and we only modify our own headers. */
--	tskb = ath_skb_removepad(skb, 0 /* Copy SKB */);
-+	tskb = ath_skb_removepad(skb, !tx /* Copy SKB */);
- 	if (tskb == NULL) {
- 		DPRINTF(sc, ATH_DEBUG_ANY,
- 			"Dropping; ath_skb_removepad failed!\n");
-@@ -6538,6 +6538,8 @@ ath_capture(struct net_device *dev, cons
- 	}
- 	
- 	ieee80211_input_monitor(ic, tskb, bf, tx, tsf, sc);
-+	if (tskb != skb)
-+		ieee80211_dev_kfree_skb(&tskb);
- }
- 
- /*
diff --git a/package/madwifi/patches/407-new_athinfo.patch b/package/madwifi/patches/407-new_athinfo.patch
deleted file mode 100644
index 6c512ad9e8..0000000000
--- a/package/madwifi/patches/407-new_athinfo.patch
+++ /dev/null
@@ -1,2352 +0,0 @@
---- a/tools/ath_info.c
-+++ b/tools/ath_info.c
-@@ -16,78 +16,8 @@
-  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-  */
- 
--/* So here is how it works:
-- *
-- * First compile...
-- *
-- * gcc ath_info.c -o ath_info
-- *
-- * then find card's physical address
-- *
-- * lspci -v
-- *
-- * 02:02.0 Ethernet controller: Atheros Communications, Inc. AR5212 802.11abg NIC (rev 01)
-- *         Subsystem: Fujitsu Limited. Unknown device 1234
-- *         Flags: bus master, medium devsel, latency 168, IRQ 23
-- *         Memory at c2000000 (32-bit, non-prefetchable) [size=64K]
-- *         Capabilities: [44] Power Management version 2
-- *
-- * address here is 0xc2000000
-- *
-- * load madwifi-ng or madwifi-old if not already loaded (be sure the
-- * interface is down!)
-- *
-- * modprobe ath_pci
-- *
-- * OR
-- *
-- * call:
-- * setpci -s 02:02.0 command=0x41f cache_line_size=0x10
-- *
-- * to enable access to the PCI device.
-- *
-- * and we run the thing...
-- *
-- * ./ath_info 0xc2000000
-- *
-- * In order to change the regdomain to 0, call:
-- *
-- * ./ath_info -w 0xc2000000 regdomain 0
-- *
-- * to change any PCI ID value, say:
-- *
-- * ./ath_info -w 0xc2000000 <name> X
-- *
-- * with <name> ::= pci_dev_id | pci_vendor_id | pci_class |
-- *                 pci_subsys_dev_id | pci_subsys_vendor_id
-- *
-- * With newer chipsets (>= AR5004x, i.e. MAC >= AR5213), Atheros introduced
-- * write protection on the EEPROM. On a GIGABYTE GN-WI01HT you can set GPIO 4
-- * to low to be able to write the EEPROM. This depends highly on the PCB layout,
-- * so there may be different GPIO used.
-- * This program currently sets GPIO 4 to low for a MAC >= AR5213, but you can
-- * override this with the -g option:
-- *
-- * ./ath_info -g 5:0 -w 0xc2000000 regdomain X
-- *
-- * would set GPIO 5 to low (and wouldn't touch GPIO 4). -g can be given several times.
-- *
-- * The write function is currently not tested with 5210 devices.
-- *
-- * Use at your own risk, entering a false device address will have really
-- * nasty results!
-- *
-- * Writing wrong values to the PCI id fields may prevent the driver from
-- * detecting the card!
-- *
-- * Transmitting on illegal frequencies may violate state laws. Stick to the local
-- * regulations!
-- *
-- * DISCLAIMER:
-- * The authors are in no case responsible for damaged hardware or violation of
-- * local laws by operating modified hardware.
-- *
-- */
-+/* Try accepting 64-bit device address even with 32-bit userspace */
-+#define _FILE_OFFSET_BITS 64
- 
- #include <stdio.h>
- #include <stdlib.h>
-@@ -130,109 +60,103 @@ fprintf(stderr, "#ERR %s: " fmt "\n", __
-  */
- #define AR5K_GPIODI	0x401c
- 
--/*
-- * Common silicon revision/version values
-- */
--enum ath5k_srev_type {
--	AR5K_VERSION_VER,
--	AR5K_VERSION_REV,
--	AR5K_VERSION_RAD,
--};
--
- struct ath5k_srev_name {
- 	const char *sr_name;
--	enum ath5k_srev_type sr_type;
--	u_int sr_val;
-+	u_int8_t sr_val;
- };
- 
--#define AR5K_SREV_UNKNOWN	0xffff
--
- /* Known MAC revision numbers */
--#define AR5K_SREV_VER_AR5210	0x00
--#define AR5K_SREV_VER_AR5311	0x10
--#define AR5K_SREV_VER_AR5311A	0x20
--#define AR5K_SREV_VER_AR5311B	0x30
--#define AR5K_SREV_VER_AR5211	0x40
--#define AR5K_SREV_VER_AR5212	0x50
--#define AR5K_SREV_VER_AR5213	0x55
--#define AR5K_SREV_VER_AR5213A	0x59
--#define	AR5K_SREV_VER_AR2424	0xa0
--#define	AR5K_SREV_VER_AR5424	0xa3
--#define	AR5K_SREV_VER_AR5413	0xa4
--#define AR5K_SREV_VER_AR5414	0xa5
--#define	AR5K_SREV_VER_AR5416	0xc0
--#define	AR5K_SREV_VER_AR5418	0xca
--#define	AR5K_SREV_VER_AR2425	0xe0
--
--/* Known PHY revision nymbers */
--#define AR5K_SREV_RAD_5110	0x00
--#define AR5K_SREV_RAD_5111	0x10
--#define AR5K_SREV_RAD_5111A	0x15
--#define AR5K_SREV_RAD_2111	0x20
--#define AR5K_SREV_RAD_5112	0x30
--#define AR5K_SREV_RAD_5112A	0x35
--#define AR5K_SREV_RAD_2112	0x40
--#define AR5K_SREV_RAD_2112A	0x45
--#define AR5K_SREV_RAD_SC1	0x63	/* Found on 5413/5414 */
--#define	AR5K_SREV_RAD_SC2	0xa2	/* Found on 2424/5424 */
--#define	AR5K_SREV_RAD_5133	0xc0	/* MIMO found on 5418 */
--
--static const struct ath5k_srev_name ath5k_srev_names[] = {
--	{"5210", AR5K_VERSION_VER, AR5K_SREV_VER_AR5210},
--	{"5311", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311},
--	{"5311A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311A},
--	{"5311B", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311B},
--	{"5211", AR5K_VERSION_VER, AR5K_SREV_VER_AR5211},
--	{"5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212},
--	{"5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213},
--	{"5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A},
--	{"2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424},
--	{"5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424},
--	{"5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413},
--	{"5414", AR5K_VERSION_VER, AR5K_SREV_VER_AR5414},
--	{"5416", AR5K_VERSION_VER, AR5K_SREV_VER_AR5416},
--	{"5418", AR5K_VERSION_VER, AR5K_SREV_VER_AR5418},
--	{"2425", AR5K_VERSION_VER, AR5K_SREV_VER_AR2425},
--	{"xxxxx", AR5K_VERSION_VER, AR5K_SREV_UNKNOWN},
--	{"5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110},
--	{"5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111},
--	{"2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111},
--	{"5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112},
--	{"5112a", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A},
--	{"2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112},
--	{"2112a", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A},
--	{"SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1},
--	{"SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2},
--	{"5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133},
--	{"xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN},
-+#define AR5K_SREV_MAC_AR5210	0x00
-+#define AR5K_SREV_MAC_AR5311	0x10
-+#define AR5K_SREV_MAC_AR5311A	0x20
-+#define AR5K_SREV_MAC_AR5311B	0x30
-+#define AR5K_SREV_MAC_AR5211	0x40
-+#define AR5K_SREV_MAC_AR5212	0x50
-+#define AR5K_SREV_MAC_AR5213	0x55
-+#define AR5K_SREV_MAC_AR5213A	0x59
-+#define AR5K_SREV_MAC_AR5513	0x61
-+#define AR5K_SREV_MAC_AR2413	0x78
-+#define AR5K_SREV_MAC_AR2414	0x79
-+#define AR5K_SREV_MAC_AR2424	0xa0
-+#define AR5K_SREV_MAC_AR5424	0xa3
-+#define AR5K_SREV_MAC_AR5413	0xa4
-+#define AR5K_SREV_MAC_AR5414	0xa5
-+#define AR5K_SREV_MAC_AR5416	0xc0
-+#define AR5K_SREV_MAC_AR5418	0xca
-+#define AR5K_SREV_MAC_AR2425	0xe2
-+
-+/* Known PHY revision numbers */
-+#define AR5K_SREV_PHY_5110	0x00
-+#define AR5K_SREV_PHY_5111	0x10
-+#define AR5K_SREV_PHY_5111A	0x15
-+#define AR5K_SREV_PHY_2111	0x20
-+#define AR5K_SREV_PHY_5112	0x30
-+#define AR5K_SREV_PHY_5112A	0x35
-+#define AR5K_SREV_PHY_2112	0x40
-+#define AR5K_SREV_PHY_2112A	0x45
-+#define AR5K_SREV_PHY_SC0	0x56	/* Found on 2413/2414 */
-+#define AR5K_SREV_PHY_SC1	0x63	/* Found on 5413/5414 */
-+#define AR5K_SREV_PHY_SC2	0xa2	/* Found on 2424/5424 */
-+#define AR5K_SREV_PHY_5133	0xc0	/* MIMO found on 5418 */
-+
-+static const struct ath5k_srev_name ath5k_mac_names[] = {
-+	{"5210", AR5K_SREV_MAC_AR5210},
-+	{"5311", AR5K_SREV_MAC_AR5311},
-+	{"5311A", AR5K_SREV_MAC_AR5311A},
-+	{"5311B", AR5K_SREV_MAC_AR5311B},
-+	{"5211", AR5K_SREV_MAC_AR5211},
-+	{"5212", AR5K_SREV_MAC_AR5212},
-+	{"5213", AR5K_SREV_MAC_AR5213},
-+	{"5213A", AR5K_SREV_MAC_AR5213A},
-+	{"2413", AR5K_SREV_MAC_AR2413},
-+	{"2414", AR5K_SREV_MAC_AR2414},
-+	{"2424", AR5K_SREV_MAC_AR2424},
-+	{"5424", AR5K_SREV_MAC_AR5424},
-+	{"5413", AR5K_SREV_MAC_AR5413},
-+	{"5414", AR5K_SREV_MAC_AR5414},
-+	{"5416", AR5K_SREV_MAC_AR5416},
-+	{"5418", AR5K_SREV_MAC_AR5418},
-+	{"2425", AR5K_SREV_MAC_AR2425},
-+};
-+
-+static const struct ath5k_srev_name ath5k_phy_names[] = {
-+	{"5110", AR5K_SREV_PHY_5110},
-+	{"5111", AR5K_SREV_PHY_5111},
-+	{"2111", AR5K_SREV_PHY_2111},
-+	{"5112", AR5K_SREV_PHY_5112},
-+	{"5112A", AR5K_SREV_PHY_5112A},
-+	{"2112", AR5K_SREV_PHY_2112},
-+	{"2112A", AR5K_SREV_PHY_2112A},
-+	{"SChip", AR5K_SREV_PHY_SC0},
-+	{"SChip", AR5K_SREV_PHY_SC1},
-+	{"SChip", AR5K_SREV_PHY_SC2},
-+	{"5133", AR5K_SREV_PHY_5133},
- };
- 
- /*
-  * Silicon revision register
-  */
- #define AR5K_SREV		0x4020	/* Register Address */
--#define AR5K_SREV_REV		0x0000000f	/* Mask for revision */
--#define AR5K_SREV_REV_S		0
--#define AR5K_SREV_VER		0x000000ff	/* Mask for version */
--#define AR5K_SREV_VER_S		4
-+#define AR5K_SREV_VER		0x000000f0	/* Mask for version */
-+#define AR5K_SREV_REV		0x000000ff	/* Mask for revision */
- 
- /*
-  * PHY chip revision register
-  */
--#define	AR5K_PHY_CHIP_ID		0x9818
-+#define AR5K_PHY_CHIP_ID		0x9818
- 
- /*
-  * PHY register
-  */
--#define	AR5K_PHY_BASE			0x9800
--#define	AR5K_PHY(_n)			(AR5K_PHY_BASE + ((_n) << 2))
-+#define AR5K_PHY_BASE			0x9800
-+#define AR5K_PHY(_n)			(AR5K_PHY_BASE + ((_n) << 2))
- #define AR5K_PHY_SHIFT_2GHZ		0x00004007
- #define AR5K_PHY_SHIFT_5GHZ		0x00000007
- 
- #define AR5K_RESET_CTL		0x4000	/* Register Address */
- #define AR5K_RESET_CTL_PCU	0x00000001	/* Protocol Control Unit reset */
- #define AR5K_RESET_CTL_DMA	0x00000002	/* DMA (Rx/Tx) reset -5210 only */
--#define	AR5K_RESET_CTL_BASEBAND	0x00000002	/* Baseband reset (5211/5212) */
-+#define AR5K_RESET_CTL_BASEBAND	0x00000002	/* Baseband reset (5211/5212) */
- #define AR5K_RESET_CTL_MAC	0x00000004	/* MAC reset (PCU+Baseband?) -5210 only */
- #define AR5K_RESET_CTL_PHY	0x00000008	/* PHY reset -5210 only */
- #define AR5K_RESET_CTL_PCI	0x00000010	/* PCI Core reset (interrupts etc) */
-@@ -253,7 +177,7 @@ static const struct ath5k_srev_name ath5
- #define AR5K_SLEEP_CTL_SLE_UNITS	0x00000008	/* not on 5210 */
- 
- #define AR5K_PCICFG			0x4010	/* Register Address */
--#define AR5K_PCICFG_EEAE		0x00000001	/* Eeprom access enable [5210] */
-+#define AR5K_PCICFG_EEAE		0x00000001	/* EEPROM access enable [5210] */
- #define AR5K_PCICFG_CLKRUNEN		0x00000004	/* CLKRUN enable [5211+] */
- #define AR5K_PCICFG_EESIZE		0x00000018	/* Mask for EEPROM size [5211+] */
- #define AR5K_PCICFG_EESIZE_S		3
-@@ -264,26 +188,118 @@ static const struct ath5k_srev_name ath5
- 
- #define AR5K_PCICFG_SPWR_DN		0x00010000	/* Mask for power status (5210) */
- 
--#define AR5K_EEPROM_BASE		0x6000
-+#define AR5K_EEPROM_BASE	0x6000
- 
--#define AR5K_EEPROM_MAGIC		0x003d	/* Offset for EEPROM Magic number */
-+/*
-+ * Common AR5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
-+ */
-+#define AR5K_EEPROM_MAGIC		0x003d	/* EEPROM Magic number */
- #define AR5K_EEPROM_MAGIC_VALUE		0x5aa5	/* Default - found on EEPROM */
- #define AR5K_EEPROM_MAGIC_5212		0x0000145c	/* 5212 */
- #define AR5K_EEPROM_MAGIC_5211		0x0000145b	/* 5211 */
- #define AR5K_EEPROM_MAGIC_5210		0x0000145a	/* 5210 */
- 
-+#define AR5K_EEPROM_PROTECT		0x003f	/* EEPROM protect status */
-+#define AR5K_EEPROM_PROTECT_RD_0_31	0x0001	/* Read protection bit for offsets 0x0 - 0x1f */
-+#define AR5K_EEPROM_PROTECT_WR_0_31	0x0002	/* Write protection bit for offsets 0x0 - 0x1f */
-+#define AR5K_EEPROM_PROTECT_RD_32_63	0x0004	/* 0x20 - 0x3f */
-+#define AR5K_EEPROM_PROTECT_WR_32_63	0x0008
-+#define AR5K_EEPROM_PROTECT_RD_64_127	0x0010	/* 0x40 - 0x7f */
-+#define AR5K_EEPROM_PROTECT_WR_64_127	0x0020
-+#define AR5K_EEPROM_PROTECT_RD_128_191	0x0040	/* 0x80 - 0xbf (regdom) */
-+#define AR5K_EEPROM_PROTECT_WR_128_191	0x0080
-+#define AR5K_EEPROM_PROTECT_RD_192_207	0x0100	/* 0xc0 - 0xcf */
-+#define AR5K_EEPROM_PROTECT_WR_192_207	0x0200
-+#define AR5K_EEPROM_PROTECT_RD_208_223	0x0400	/* 0xd0 - 0xdf */
-+#define AR5K_EEPROM_PROTECT_WR_208_223	0x0800
-+#define AR5K_EEPROM_PROTECT_RD_224_239	0x1000	/* 0xe0 - 0xef */
-+#define AR5K_EEPROM_PROTECT_WR_224_239	0x2000
-+#define AR5K_EEPROM_PROTECT_RD_240_255	0x4000	/* 0xf0 - 0xff */
-+#define AR5K_EEPROM_PROTECT_WR_240_255	0x8000
-+#define AR5K_EEPROM_REG_DOMAIN		0x00bf	/* EEPROM regdom */
-+#define AR5K_EEPROM_INFO_BASE		0x00c0	/* EEPROM header */
-+#define AR5K_EEPROM_INFO_MAX		(0x400 - AR5K_EEPROM_INFO_BASE)
-+#define AR5K_EEPROM_INFO_CKSUM		0xffff
-+#define AR5K_EEPROM_INFO(_n)		(AR5K_EEPROM_INFO_BASE + (_n))
-+
-+#define AR5K_EEPROM_VERSION		AR5K_EEPROM_INFO(1)	/* EEPROM Version */
-+#define AR5K_EEPROM_VERSION_3_0		0x3000	/* No idea what's going on before this version */
-+#define AR5K_EEPROM_VERSION_3_1		0x3001	/* ob/db values for 2GHz (AR5211_rfregs) */
-+#define AR5K_EEPROM_VERSION_3_2		0x3002	/* different frequency representation (eeprom_bin2freq) */
-+#define AR5K_EEPROM_VERSION_3_3		0x3003	/* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
-+#define AR5K_EEPROM_VERSION_3_4		0x3004	/* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */
-+#define AR5K_EEPROM_VERSION_4_0		0x4000	/* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
-+#define AR5K_EEPROM_VERSION_4_1		0x4001	/* has ee_margin_tx_rx (eeprom_init) */
-+#define AR5K_EEPROM_VERSION_4_2		0x4002	/* has ee_cck_ofdm_gain_delta (eeprom_init) */
-+#define AR5K_EEPROM_VERSION_4_3		0x4003
-+#define AR5K_EEPROM_VERSION_4_4		0x4004
-+#define AR5K_EEPROM_VERSION_4_5		0x4005
-+#define AR5K_EEPROM_VERSION_4_6		0x4006	/* has ee_scaled_cck_delta */
-+#define AR5K_EEPROM_VERSION_4_7		0x3007
-+
-+#define AR5K_EEPROM_MODE_11A		0
-+#define AR5K_EEPROM_MODE_11B		1
-+#define AR5K_EEPROM_MODE_11G		2
-+
-+#define AR5K_EEPROM_HDR			AR5K_EEPROM_INFO(2)	/* Header that contains the device caps */
-+#define AR5K_EEPROM_HDR_11A(_v)		(((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
-+#define AR5K_EEPROM_HDR_11B(_v)		(((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
-+#define AR5K_EEPROM_HDR_11G(_v)		(((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
-+#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v)	(((_v) >> 3) & 0x1)	/* Disable turbo for 2GHz (?) */
-+#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v)	(((_v) >> 4) & 0x7f)	/* Max turbo power for a/XR mode (eeprom_init) */
-+#define AR5K_EEPROM_HDR_DEVICE(_v)	(((_v) >> 11) & 0x7)
-+#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v)	(((_v) >> 15) & 0x1)	/* Disable turbo for 5GHz (?) */
-+#define AR5K_EEPROM_HDR_RFKILL(_v)	(((_v) >> 14) & 0x1)	/* Device has RFKill support */
-+
-+/* Misc values available since EEPROM 4.0 */
-+#define AR5K_EEPROM_MISC0		AR5K_EEPROM_INFO(4)
-+#define AR5K_EEPROM_EARSTART(_v)	((_v) & 0xfff)
-+#define AR5K_EEPROM_HDR_XR2_DIS(_v)	(((_v) >> 12) & 0x1)
-+#define AR5K_EEPROM_HDR_XR5_DIS(_v)	(((_v) >> 13) & 0x1)
-+#define AR5K_EEPROM_EEMAP(_v)		(((_v) >> 14) & 0x3)
-+#define AR5K_EEPROM_MISC1		AR5K_EEPROM_INFO(5)
-+#define AR5K_EEPROM_TARGET_PWRSTART(_v)	((_v) & 0xfff)
-+#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v)	(((_v) >> 14) & 0x1)
-+
-+#define AR5K_EEPROM_RFKILL_GPIO_SEL	0x0000001c
-+#define AR5K_EEPROM_RFKILL_GPIO_SEL_S	2
-+#define AR5K_EEPROM_RFKILL_POLARITY	0x00000002
-+#define AR5K_EEPROM_RFKILL_POLARITY_S	1
-+
-+/* Newer EEPROMs are using a different offset */
-+#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
-+	(((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
-+
-+#define AR5K_EEPROM_ANT_GAIN(_v)	AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
-+#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v)	((int8_t)(((_v) >> 8) & 0xff))
-+#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v)	((int8_t)((_v) & 0xff))
-+
-+/* calibration settings */
-+#define AR5K_EEPROM_MODES_11A(_v)	AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
-+#define AR5K_EEPROM_MODES_11B(_v)	AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
-+#define AR5K_EEPROM_MODES_11G(_v)	AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
-+#define AR5K_EEPROM_CTL(_v)		AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128)	/* Conformance test limits */
-+#define AR5K_EEPROM_CHANNELS_5GHZ(_v)	AR5K_EEPROM_OFF(_v, 0x0100, 0x0150)	/* List of calibrated 5GHz chans */
-+#define	AR5K_EEPROM_TARGET_PWR_OFF_11A(_v)	AR5K_EEPROM_OFF(_v, AR5K_EEPROM_CHANNELS_5GHZ(_v) + 0x0055, 0x0000)
-+#define	AR5K_EEPROM_TARGET_PWR_OFF_11B(_v)	AR5K_EEPROM_OFF(_v, AR5K_EEPROM_CHANNELS_5GHZ(_v) + 0x0065, 0x0010)
-+#define	AR5K_EEPROM_TARGET_PWR_OFF_11G(_v)	AR5K_EEPROM_OFF(_v, AR5K_EEPROM_CHANNELS_5GHZ(_v) + 0x0069, 0x0014)
-+
-+/* [3.1 - 3.3] */
-+#define AR5K_EEPROM_OBDB0_2GHZ		0x00ec
-+#define AR5K_EEPROM_OBDB1_2GHZ		0x00ed
-+
- /*
-  * EEPROM data register
-  */
- #define AR5K_EEPROM_DATA_5211	0x6004
- #define AR5K_EEPROM_DATA_5210	0x6800
--#define	AR5K_EEPROM_DATA	(mac_version == AR5K_SREV_VER_AR5210 ? \
-+#define AR5K_EEPROM_DATA	(mac_version == AR5K_SREV_MAC_AR5210 ? \
- 				AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211)
- 
- /*
-  * EEPROM command register
-  */
--#define AR5K_EEPROM_CMD		0x6008	/* Register Addres */
-+#define AR5K_EEPROM_CMD		0x6008			/* Register Address */
- #define AR5K_EEPROM_CMD_READ	0x00000001	/* EEPROM read */
- #define AR5K_EEPROM_CMD_WRITE	0x00000002	/* EEPROM write */
- #define AR5K_EEPROM_CMD_RESET	0x00000004	/* EEPROM reset */
-@@ -291,43 +307,163 @@ static const struct ath5k_srev_name ath5
- /*
-  * EEPROM status register
-  */
--#define AR5K_EEPROM_STAT_5210	0x6c00	/* Register Address [5210] */
--#define AR5K_EEPROM_STAT_5211	0x600c	/* Register Address [5211+] */
--#define	AR5K_EEPROM_STATUS	(mac_version == AR5K_SREV_VER_AR5210 ? \
-+#define AR5K_EEPROM_STAT_5210	0x6c00			/* Register Address [5210] */
-+#define AR5K_EEPROM_STAT_5211	0x600c			/* Register Address [5211+] */
-+#define AR5K_EEPROM_STATUS	(mac_version == AR5K_SREV_MAC_AR5210 ? \
- 				AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211)
- #define AR5K_EEPROM_STAT_RDERR	0x00000001	/* EEPROM read failed */
- #define AR5K_EEPROM_STAT_RDDONE	0x00000002	/* EEPROM read successful */
- #define AR5K_EEPROM_STAT_WRERR	0x00000004	/* EEPROM write failed */
- #define AR5K_EEPROM_STAT_WRDONE	0x00000008	/* EEPROM write successful */
- 
--#define AR5K_EEPROM_REG_DOMAIN		0x00bf	/* Offset for EEPROM regulatory domain */
--#define AR5K_EEPROM_INFO_BASE		0x00c0	/* Offset for EEPROM header */
--#define AR5K_EEPROM_INFO_MAX		(0x400 - AR5K_EEPROM_INFO_BASE)
--#define AR5K_EEPROM_INFO_CKSUM		0xffff
--#define AR5K_EEPROM_INFO(_n)		(AR5K_EEPROM_INFO_BASE + (_n))
--#define AR5K_EEPROM_MODE_11A		0
--#define AR5K_EEPROM_MODE_11B		1
--#define AR5K_EEPROM_MODE_11G		2
-+/*
-+ * EEPROM config register (?)
-+ */
-+#define AR5K_EEPROM_CFG	0x6010
- 
--#define AR5K_EEPROM_VERSION		AR5K_EEPROM_INFO(1)
-+/* Some EEPROM defines */
-+#define AR5K_EEPROM_EEP_SCALE		100
-+#define AR5K_EEPROM_EEP_DELTA		10
-+#define AR5K_EEPROM_N_MODES		3
-+#define AR5K_EEPROM_N_5GHZ_CHAN		10
-+#define AR5K_EEPROM_N_2GHZ_CHAN		3
-+#define AR5K_EEPROM_MAX_CHAN		10
-+#define AR5K_EEPROM_N_PCDAC		11
-+#define AR5K_EEPROM_N_TEST_FREQ		8
-+#define AR5K_EEPROM_N_EDGES		8
-+#define AR5K_EEPROM_N_INTERCEPTS	11
-+#define AR5K_EEPROM_FREQ_M(_v)		AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
-+#define AR5K_EEPROM_PCDAC_M		0x3f
-+#define AR5K_EEPROM_PCDAC_START		1
-+#define AR5K_EEPROM_PCDAC_STOP		63
-+#define AR5K_EEPROM_PCDAC_STEP		1
-+#define AR5K_EEPROM_NON_EDGE_M		0x40
-+#define AR5K_EEPROM_CHANNEL_POWER	8
-+#define AR5K_EEPROM_N_OBDB		4
-+#define AR5K_EEPROM_OBDB_DIS		0xffff
-+#define AR5K_EEPROM_CHANNEL_DIS		0xff
-+#define AR5K_EEPROM_SCALE_OC_DELTA(_x)	(((_x) * 2) / 10)
-+#define AR5K_EEPROM_N_CTLS(_v)		AR5K_EEPROM_OFF(_v, 16, 32)
-+#define AR5K_EEPROM_MAX_CTLS		32
-+#define AR5K_EEPROM_N_XPD_PER_CHANNEL	4
-+#define AR5K_EEPROM_N_XPD0_POINTS	4
-+#define AR5K_EEPROM_N_XPD3_POINTS	3
-+#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ	35
-+#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ	55
-+#define AR5K_EEPROM_POWER_M		0x3f
-+#define AR5K_EEPROM_POWER_MIN		0
-+#define AR5K_EEPROM_POWER_MAX		3150
-+#define AR5K_EEPROM_POWER_STEP		50
-+#define AR5K_EEPROM_POWER_TABLE_SIZE	64
-+#define AR5K_EEPROM_N_POWER_LOC_11B	4
-+#define AR5K_EEPROM_N_POWER_LOC_11G	6
-+#define AR5K_EEPROM_I_GAIN		10
-+#define AR5K_EEPROM_CCK_OFDM_DELTA	15
-+#define AR5K_EEPROM_N_IQ_CAL		2
-+
-+enum ath5k_ant_setting {
-+	AR5K_ANT_VARIABLE	= 0,	/* variable by programming */
-+	AR5K_ANT_FIXED_A	= 1,	/* fixed to 11a frequencies */
-+	AR5K_ANT_FIXED_B	= 2,	/* fixed to 11b frequencies */
-+	AR5K_ANT_MAX		= 3,
-+};
- 
--#define AR5K_EEPROM_HDR			AR5K_EEPROM_INFO(2)	/* Header that contains the device caps */
--#define AR5K_EEPROM_HDR_11A(_v)		(((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)	/* Device has a support */
--#define AR5K_EEPROM_HDR_11B(_v)		(((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)	/* Device has b support */
--#define AR5K_EEPROM_HDR_11G(_v)		(((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)	/* Device has g support */
--#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v)	(((_v) >> 3) & 0x1)	/* Disable turbo for 2Ghz (?) */
--#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v)	(((_v) >> 4) & 0x7f)	/* Max turbo power for a/XR mode (eeprom_init) */
--#define AR5K_EEPROM_HDR_DEVICE(_v)	(((_v) >> 11) & 0x7)
--#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v)	(((_v) >> 15) & 0x1)	/* Disable turbo for 5Ghz (?) */
--#define AR5K_EEPROM_HDR_RFKILL(_v)	(((_v) >> 14) & 0x1)	/* Device has RFKill support */
-+/* Per channel calibration data, used for power table setup */
-+struct ath5k_chan_pcal_info {
-+	u_int16_t	freq; /* Frequency */
-+	/* Power levels in dBm * 4 units */
-+	int16_t		pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
-+	int16_t		pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
-+	/* PCDAC tables in dBm * 2 units */
-+	u_int16_t	pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
-+	u_int16_t	pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
-+	/* Max available power */
-+	u_int16_t	max_pwr;
-+};
- 
--/* Misc values available since EEPROM 4.0 */
--#define AR5K_EEPROM_MISC0		0x00c4
--#define AR5K_EEPROM_EARSTART(_v)	((_v) & 0xfff)
--#define AR5K_EEPROM_EEMAP(_v)		(((_v) >> 14) & 0x3)
--#define AR5K_EEPROM_MISC1		0x00c5
--#define AR5K_EEPROM_TARGET_PWRSTART(_v)	((_v) & 0xfff)
--#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v)	(((_v) >> 14) & 0x1)
-+/* Per rate calibration data for each mode, used for power table setup */
-+struct ath5k_rate_pcal_info {
-+	u_int16_t	freq; /* Frequency */
-+	/* Power level for 6-24Mbit/s rates */
-+	u_int16_t	target_power_6to24;
-+	/* Power level for 36Mbit rate */
-+	u_int16_t	target_power_36;
-+	/* Power level for 48Mbit rate */
-+	u_int16_t	target_power_48;
-+	/* Power level for 54Mbit rate */
-+	u_int16_t	target_power_54;
-+};
-+
-+/* EEPROM calibration data */
-+struct ath5k_eeprom_info {
-+
-+	/* Header information */
-+	u_int16_t	ee_magic;
-+	u_int16_t	ee_protect;
-+	u_int16_t	ee_regdomain;
-+	u_int16_t	ee_version;
-+	u_int16_t	ee_header;
-+	u_int16_t	ee_ant_gain;
-+	u_int16_t	ee_misc0;
-+	u_int16_t	ee_misc1;
-+	u_int16_t	ee_cck_ofdm_gain_delta;
-+	u_int16_t	ee_cck_ofdm_power_delta;
-+	u_int16_t	ee_scaled_cck_delta;
-+
-+	/* Used for tx thermal adjustment (eeprom_init, rfregs) */
-+	u_int16_t	ee_tx_clip;
-+	u_int16_t	ee_pwd_84;
-+	u_int16_t	ee_pwd_90;
-+	u_int16_t	ee_gain_select;
-+
-+	/* RF Calibration settings (reset, rfregs) */
-+	u_int16_t	ee_i_cal[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_q_cal[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_fixed_bias[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_turbo_max_power[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_xr_power[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_switch_settling[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_ant_tx_rx[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
-+	u_int16_t	ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
-+	u_int16_t	ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
-+	u_int16_t	ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_thr_62[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_xlna_gain[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_xpd[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_x_gain[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_i_gain[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
-+
-+	/* Power calibration data */
-+	u_int16_t	ee_false_detect[AR5K_EEPROM_N_MODES];
-+	u_int16_t	ee_cal_piers_a;
-+	struct ath5k_chan_pcal_info	ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
-+	u_int16_t	ee_cal_piers_b;
-+	struct ath5k_chan_pcal_info	ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN];
-+	u_int16_t	ee_cal_piers_g;
-+	struct ath5k_chan_pcal_info	ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN];
-+	/* Per rate target power levels */
-+	u_int16_t	ee_rate_target_pwr_num_a;
-+	struct ath5k_rate_pcal_info	ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
-+	u_int16_t	ee_rate_target_pwr_num_b;
-+	struct ath5k_rate_pcal_info	ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN];
-+	u_int16_t	ee_rate_target_pwr_num_g;
-+	struct ath5k_rate_pcal_info	ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN];
-+
-+	/* Conformance test limits (Unused) */
-+	u_int16_t	ee_ctls;
-+	u_int16_t	ee_ctl[AR5K_EEPROM_MAX_CTLS];
-+
-+	/* Noise Floor Calibration settings */
-+	int16_t		ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
-+	int8_t		ee_adc_desired_size[AR5K_EEPROM_N_MODES];
-+	int8_t		ee_pga_desired_size[AR5K_EEPROM_N_MODES];
-+
-+	u_int32_t	ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
-+};
- 
- /*
-  * Read data by masking
-@@ -350,7 +486,6 @@ static const struct ath5k_srev_name ath5
- 	(*((volatile u_int32_t *)(mem + (_reg))) = (_val))
- #endif
- 
--
- #define AR5K_REG_ENABLE_BITS(_reg, _flags)	\
- 	AR5K_REG_WRITE(_reg, AR5K_REG_READ(_reg) | (_flags))
- 
-@@ -359,7 +494,12 @@ static const struct ath5k_srev_name ath5
- 
- #define AR5K_TUNE_REGISTER_TIMEOUT		20000
- 
--/* names for eeprom fields */
-+#define AR5K_EEPROM_READ(_o, _v) do {					\
-+	if ((ret = ath5k_hw_eeprom_read(mem, (_o), &(_v), mac_version)) != 0)	\
-+		return (ret);						\
-+} while (0)
-+
-+/* Names for EEPROM fields */
- struct eeprom_entry {
- 	const char *name;
- 	int addr;
-@@ -375,8 +515,6 @@ static const struct eeprom_entry eeprom_
- 	{"regdomain", AR5K_EEPROM_REG_DOMAIN},
- };
- 
--static const int eeprom_addr_len = sizeof(eeprom_addr) / sizeof(eeprom_addr[0]);
--
- static int force_write = 0;
- static int verbose = 0;
- 
-@@ -398,8 +536,8 @@ static u_int32_t ath5k_hw_bitswap(u_int3
- /*
-  * Get the PHY Chip revision
-  */
--static u_int16_t
--ath5k_hw_radio_revision(u_int16_t mac_version, void *mem, u_int8_t chip)
-+static u_int16_t ath5k_hw_radio_revision(u_int16_t mac_version, void *mem,
-+					 u_int8_t chip)
- {
- 	int i;
- 	u_int32_t srev;
-@@ -427,7 +565,7 @@ ath5k_hw_radio_revision(u_int16_t mac_ve
- 	for (i = 0; i < 8; i++)
- 		AR5K_REG_WRITE(AR5K_PHY(0x20), 0x00010000);
- 
--	if (mac_version == AR5K_SREV_VER_AR5210) {
-+	if (mac_version == AR5K_SREV_MAC_AR5210) {
- 		srev = AR5K_REG_READ(AR5K_PHY(256) >> 28) & 0xf;
- 
- 		ret = (u_int16_t)ath5k_hw_bitswap(srev, 4) + 1;
-@@ -447,9 +585,8 @@ ath5k_hw_radio_revision(u_int16_t mac_ve
- /*
-  * Write to EEPROM
-  */
--static int
--ath5k_hw_eeprom_write(void *mem, u_int32_t offset, u_int16_t data,
--		      u_int8_t mac_version)
-+static int ath5k_hw_eeprom_write(void *mem, u_int32_t offset, u_int16_t data,
-+				 u_int8_t mac_version)
- {
- 	u_int32_t status, timeout;
- 
-@@ -457,7 +594,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
- 	 * Initialize EEPROM access
- 	 */
- 
--	if (mac_version == AR5K_SREV_VER_AR5210) {
-+	if (mac_version == AR5K_SREV_MAC_AR5210) {
- 
- 		AR5K_REG_ENABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_EEAE);
- 
-@@ -466,7 +603,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
- 
- 	} else {
- 		/* not 5210 */
--		/* reset eeprom access */
-+		/* reset EEPROM access */
- 		AR5K_REG_WRITE(AR5K_EEPROM_CMD, AR5K_EEPROM_CMD_RESET);
- 		usleep(5);
- 
-@@ -484,7 +621,7 @@ ath5k_hw_eeprom_write(void *mem, u_int32
- 		status = AR5K_REG_READ(AR5K_EEPROM_STATUS);
- 		if (status & AR5K_EEPROM_STAT_WRDONE) {
- 			if (status & AR5K_EEPROM_STAT_WRERR) {
--				err("eeprom write access to 0x%04x failed",
-+				err("EEPROM write access to 0x%04x failed",
- 				    offset);
- 				return 1;
- 			}
-@@ -499,16 +636,15 @@ ath5k_hw_eeprom_write(void *mem, u_int32
- /*
-  * Read from EEPROM
-  */
--static int
--ath5k_hw_eeprom_read(void *mem, u_int32_t offset, u_int16_t *data,
--		     u_int8_t mac_version)
-+static int ath5k_hw_eeprom_read(void *mem, u_int32_t offset, u_int16_t *data,
-+				u_int8_t mac_version)
- {
- 	u_int32_t status, timeout;
- 
- 	/*
- 	 * Initialize EEPROM access
- 	 */
--	if (mac_version == AR5K_SREV_VER_AR5210) {
-+	if (mac_version == AR5K_SREV_MAC_AR5210) {
- 		AR5K_REG_ENABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_EEAE);
- 		(void)AR5K_REG_READ(AR5K_EEPROM_BASE + (4 * offset));
- 	} else {
-@@ -531,50 +667,701 @@ ath5k_hw_eeprom_read(void *mem, u_int32_
- 	return 1;
- }
- 
--static const char *ath5k_hw_get_part_name(enum ath5k_srev_type type,
--					  u_int32_t val)
-+/*
-+ * Translate binary channel representation in EEPROM to frequency
-+ */
-+static u_int16_t ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee,
-+				       u_int16_t bin, unsigned int mode)
- {
--	const char *name = "xxxxx";
--	int i;
-+	u_int16_t val;
- 
--	for (i = 0; i < ARRAY_SIZE(ath5k_srev_names); i++) {
--		if (ath5k_srev_names[i].sr_type != type ||
--		    ath5k_srev_names[i].sr_val == AR5K_SREV_UNKNOWN)
--			continue;
--		if ((val & 0xff) < ath5k_srev_names[i + 1].sr_val) {
--			name = ath5k_srev_names[i].sr_name;
-+	if (bin == AR5K_EEPROM_CHANNEL_DIS)
-+		return bin;
-+
-+	if (mode == AR5K_EEPROM_MODE_11A) {
-+		if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
-+			val = (5 * bin) + 4800;
-+		else
-+			val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
-+			    (bin * 10) + 5100;
-+	} else {
-+		if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
-+			val = bin + 2300;
-+		else
-+			val = bin + 2400;
-+	}
-+
-+	return val;
-+}
-+
-+/*
-+ * Read antenna info from EEPROM
-+ */
-+static int ath5k_eeprom_read_ants(void *mem, u_int8_t mac_version,
-+				  struct ath5k_eeprom_info *ee,
-+				  u_int32_t *offset, unsigned int mode)
-+{
-+	u_int32_t o = *offset;
-+	u_int16_t val;
-+	int ret, i = 0;
-+
-+	AR5K_EEPROM_READ(o++, val);
-+	ee->ee_switch_settling[mode]	= (val >> 8) & 0x7f;
-+	ee->ee_ant_tx_rx[mode]		= (val >> 2) & 0x3f;
-+	ee->ee_ant_control[mode][i]	= (val << 4) & 0x3f;
-+
-+	AR5K_EEPROM_READ(o++, val);
-+	ee->ee_ant_control[mode][i++]	|= (val >> 12) & 0xf;
-+	ee->ee_ant_control[mode][i++]	= (val >> 6) & 0x3f;
-+	ee->ee_ant_control[mode][i++]	= val & 0x3f;
-+
-+	AR5K_EEPROM_READ(o++, val);
-+	ee->ee_ant_control[mode][i++]	= (val >> 10) & 0x3f;
-+	ee->ee_ant_control[mode][i++]	= (val >> 4) & 0x3f;
-+	ee->ee_ant_control[mode][i]	= (val << 2) & 0x3f;
-+
-+	AR5K_EEPROM_READ(o++, val);
-+	ee->ee_ant_control[mode][i++]	|= (val >> 14) & 0x3;
-+	ee->ee_ant_control[mode][i++]	= (val >> 8) & 0x3f;
-+	ee->ee_ant_control[mode][i++]	= (val >> 2) & 0x3f;
-+	ee->ee_ant_control[mode][i]	= (val << 4) & 0x3f;
-+
-+	AR5K_EEPROM_READ(o++, val);
-+	ee->ee_ant_control[mode][i++]	|= (val >> 12) & 0xf;
-+	ee->ee_ant_control[mode][i++]	= (val >> 6) & 0x3f;
-+	ee->ee_ant_control[mode][i++]	= val & 0x3f;
-+
-+	/* Get antenna modes */
-+	ee->ee_antenna[mode][0] =
-+	    (ee->ee_ant_control[mode][0] << 4) | 0x1;
-+	ee->ee_antenna[mode][AR5K_ANT_FIXED_A] =
-+	     ee->ee_ant_control[mode][1]	|
-+	    (ee->ee_ant_control[mode][2] << 6)	|
-+	    (ee->ee_ant_control[mode][3] << 12) |
-+	    (ee->ee_ant_control[mode][4] << 18) |
-+	    (ee->ee_ant_control[mode][5] << 24);
-+	ee->ee_antenna[mode][AR5K_ANT_FIXED_B] =
-+	     ee->ee_ant_control[mode][6]	|
-+	    (ee->ee_ant_control[mode][7] << 6)	|
-+	    (ee->ee_ant_control[mode][8] << 12) |
-+	    (ee->ee_ant_control[mode][9] << 18) |
-+	    (ee->ee_ant_control[mode][10] << 24);
-+
-+	/* return new offset */
-+	*offset = o;
-+
-+	return 0;
-+}
-+
-+/*
-+ * Read supported modes from EEPROM
-+ */
-+static int ath5k_eeprom_read_modes(void *mem, u_int8_t mac_version,
-+				   struct ath5k_eeprom_info *ee,
-+				   u_int32_t *offset, unsigned int mode)
-+{
-+	u_int32_t o = *offset;
-+	u_int16_t val;
-+	int ret;
-+
-+	AR5K_EEPROM_READ(o++, val);
-+	ee->ee_tx_end2xlna_enable[mode]	= (val >> 8) & 0xff;
-+	ee->ee_thr_62[mode]		= val & 0xff;
-+
-+	if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2)
-+		ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
-+
-+	AR5K_EEPROM_READ(o++, val);
-+	ee->ee_tx_end2xpa_disable[mode]	= (val >> 8) & 0xff;
-+	ee->ee_tx_frm2xpa_enable[mode]	= val & 0xff;
-+
-+	AR5K_EEPROM_READ(o++, val);
-+	ee->ee_pga_desired_size[mode]	= (val >> 8) & 0xff;
-+
-+	if ((val & 0xff) & 0x80)
-+		ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
-+	else
-+		ee->ee_noise_floor_thr[mode] = val & 0xff;
-+
-+	if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2)
-+		ee->ee_noise_floor_thr[mode] =
-+		    mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
-+
-+	AR5K_EEPROM_READ(o++, val);
-+	ee->ee_xlna_gain[mode]		= (val >> 5) & 0xff;
-+	ee->ee_x_gain[mode]		= (val >> 1) & 0xf;
-+	ee->ee_xpd[mode]		= val & 0x1;
-+
-+	if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
-+		ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
-+
-+	if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
-+		AR5K_EEPROM_READ(o++, val);
-+		ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
-+
-+		if (mode == AR5K_EEPROM_MODE_11A)
-+			ee->ee_xr_power[mode] = val & 0x3f;
-+		else {
-+			ee->ee_ob[mode][0] = val & 0x7;
-+			ee->ee_db[mode][0] = (val >> 3) & 0x7;
-+		}
-+	}
-+
-+	if (ee->ee_version < AR5K_EEPROM_VERSION_3_4) {
-+		ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
-+		ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
-+	} else {
-+		ee->ee_i_gain[mode] = (val >> 13) & 0x7;
-+
-+		AR5K_EEPROM_READ(o++, val);
-+		ee->ee_i_gain[mode] |= (val << 3) & 0x38;
-+
-+		if (mode == AR5K_EEPROM_MODE_11G)
-+			ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
-+	}
-+
-+	if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0 &&
-+	    mode == AR5K_EEPROM_MODE_11A) {
-+		ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
-+		ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
-+	}
-+
-+	if (ee->ee_version >= AR5K_EEPROM_VERSION_4_6 &&
-+	    mode == AR5K_EEPROM_MODE_11G)
-+		ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
-+
-+	/* return new offset */
-+	*offset = o;
-+
-+	return 0;
-+}
-+
-+/*
-+ * Read per channel calibration info from EEPROM
-+ * This doesn't work on 2112+ chips (EEPROM versions >= 4.6),
-+ * I only tested it on 5213 + 5112. This is still work in progress...
-+ *
-+ * This info is used to calibrate the baseband power table. Imagine
-+ * that for each channel there is a power curve that's hw specific
-+ * (depends on amplifier) and we try to "correct" this curve using offests
-+ * we pass on to phy chip (baseband -> before amplifier) so that it can
-+ * use acurate power values when setting tx power (takes amplifier's performance
-+ * on each channel into account).
-+ *
-+ * EEPROM provides us with the offsets for some pre-calibrated channels
-+ * and we have to scale (to create the full table for these channels) and
-+ * interpolate (in order to create the table for any channel).
-+ */
-+static int ath5k_eeprom_read_pcal_info(void *mem, u_int8_t mac_version,
-+				       struct ath5k_eeprom_info *ee,
-+				       u_int32_t *offset, unsigned int mode)
-+{
-+	u_int32_t o = *offset;
-+	unsigned int i, c;
-+	int ret;
-+	u_int16_t val;
-+	struct ath5k_chan_pcal_info *chan_pcal_info;
-+	u_int16_t cal_piers;
-+
-+	switch (mode) {
-+	case AR5K_EEPROM_MODE_11A:
-+		chan_pcal_info = ee->ee_pwr_cal_a;
-+		cal_piers = ee->ee_cal_piers_a;
-+		break;
-+	case AR5K_EEPROM_MODE_11B:
-+		chan_pcal_info = ee->ee_pwr_cal_b;
-+		cal_piers = ee->ee_cal_piers_b;
-+		break;
-+	case AR5K_EEPROM_MODE_11G:
-+		chan_pcal_info = ee->ee_pwr_cal_g;
-+		cal_piers = ee->ee_cal_piers_g;
-+		break;
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	for (i = 0; i < cal_piers; i++) {
-+		/* Power values in dBm * 4 */
-+		for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
-+			AR5K_EEPROM_READ(o++, val);
-+			chan_pcal_info[i].pwr_x0[c] = (val & 0xff);
-+			chan_pcal_info[i].pwr_x0[++c] = ((val >> 8) & 0xff);
-+		}
-+
-+		/* PCDAC steps (dBm * 2) */
-+		AR5K_EEPROM_READ(o++, val);
-+		chan_pcal_info[i].pcdac_x0[1] = (val & 0x1f);
-+		chan_pcal_info[i].pcdac_x0[2] = ((val >> 5) & 0x1f);
-+		chan_pcal_info[i].pcdac_x0[3] = ((val >> 10) & 0x1f);
-+
-+		/* No idea what these power levels are for (4 xpds ?)
-+		   I got zeroes on my card and the EEPROM info
-+		   dumps we found on the net also have weird values */
-+		AR5K_EEPROM_READ(o++, val);
-+		chan_pcal_info[i].pwr_x3[0] = (val & 0xff);
-+		chan_pcal_info[i].pwr_x3[1] = ((val >> 8) & 0xff);
-+
-+		AR5K_EEPROM_READ(o++, val);
-+		chan_pcal_info[i].pwr_x3[2] = (val & 0xff);
-+		/* It's weird but they put it here, that's the
-+		   PCDAC starting step */
-+		chan_pcal_info[i].pcdac_x0[0] = ((val >> 8) & 0xff);
-+
-+		/* Static values seen on EEPROM info dumps */
-+		chan_pcal_info[i].pcdac_x3[0] = 20;
-+		chan_pcal_info[i].pcdac_x3[1] = 35;
-+		chan_pcal_info[i].pcdac_x3[2] = 63;
-+
-+		/* Last xpd0 power level is also channel maximum */
-+		chan_pcal_info[i].max_pwr = chan_pcal_info[i].pwr_x0[3];
-+
-+		/* Recreate pcdac_x0 table for this channel using pcdac steps */
-+		chan_pcal_info[i].pcdac_x0[1] += chan_pcal_info[i].pcdac_x0[0];
-+		chan_pcal_info[i].pcdac_x0[2] += chan_pcal_info[i].pcdac_x0[1];
-+		chan_pcal_info[i].pcdac_x0[3] += chan_pcal_info[i].pcdac_x0[2];
-+	}
-+
-+	/* return new offset */
-+	(*offset) = o;
-+
-+	return 0;
-+}
-+
-+/*
-+ * Read per rate target power (this is the maximum tx power
-+ * supported by the card). This info is used when setting
-+ * tx power, no matter the channel.
-+ *
-+ * This also works for v5 EEPROMs.
-+ */
-+static int ath5k_eeprom_read_target_rate_pwr_info(void *mem,
-+						  u_int8_t mac_version,
-+						  struct ath5k_eeprom_info *ee,
-+						  u_int32_t *offset,
-+						  unsigned int mode)
-+{
-+	u_int32_t o = *offset;
-+	u_int16_t val;
-+	struct ath5k_rate_pcal_info *rate_pcal_info;
-+	u_int16_t *rate_target_pwr_num;
-+	int ret, i;
-+
-+	switch (mode) {
-+	case AR5K_EEPROM_MODE_11A:
-+		rate_pcal_info = ee->ee_rate_tpwr_a;
-+		ee->ee_rate_target_pwr_num_a = AR5K_EEPROM_N_5GHZ_CHAN;
-+		rate_target_pwr_num = &ee->ee_rate_target_pwr_num_a;
-+		break;
-+	case AR5K_EEPROM_MODE_11B:
-+		rate_pcal_info = ee->ee_rate_tpwr_b;
-+		ee->ee_rate_target_pwr_num_b = 2; /* 3rd is g mode'ss 1st */
-+		rate_target_pwr_num = &ee->ee_rate_target_pwr_num_b;
-+		break;
-+	case AR5K_EEPROM_MODE_11G:
-+		rate_pcal_info = ee->ee_rate_tpwr_g;
-+		ee->ee_rate_target_pwr_num_g = AR5K_EEPROM_N_2GHZ_CHAN;
-+		rate_target_pwr_num = &ee->ee_rate_target_pwr_num_g;
-+		break;
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	/* Different freq mask for older eeproms (<= v3.2) */
-+	if(ee->ee_version <= 0x3002){
-+		for (i = 0; i < (*rate_target_pwr_num); i++) {
-+			AR5K_EEPROM_READ(o++, val);
-+			rate_pcal_info[i].freq =
-+			    ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
-+	
-+			rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
-+			rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
-+	
-+			AR5K_EEPROM_READ(o++, val);
-+	
-+			if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
-+			    val == 0) {
-+				(*rate_target_pwr_num) = i;
-+				break;
-+			}
-+
-+			rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
-+			rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
-+			rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
-+		}
-+	} else {
-+		for (i = 0; i < (*rate_target_pwr_num); i++) {
-+			AR5K_EEPROM_READ(o++, val);
-+			rate_pcal_info[i].freq =
-+			    ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
-+	
-+			rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
-+			rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
-+	
-+			AR5K_EEPROM_READ(o++, val);
-+	
-+			if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
-+			    val == 0) {
-+				(*rate_target_pwr_num) = i;
-+				break;
-+			}
-+
-+			rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
-+			rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
-+			rate_pcal_info[i].target_power_54 = (val & 0x3f);
-+		}
-+	}
-+	/* return new offset */
-+	(*offset) = o;
-+
-+	return 0;
-+}
-+
-+/*
-+ * Initialize EEPROM & capabilities data
-+ */
-+static int ath5k_eeprom_init(void *mem, u_int8_t mac_version,
-+			     struct ath5k_eeprom_info *ee)
-+{
-+	unsigned int mode, i;
-+	int ret;
-+	u_int32_t offset;
-+	u_int16_t val;
-+
-+	/* Initial TX thermal adjustment values */
-+	ee->ee_tx_clip = 4;
-+	ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
-+	ee->ee_gain_select = 1;
-+
-+	/*
-+	 * Read values from EEPROM and store them in the capability structure
-+	 */
-+	AR5K_EEPROM_READ(AR5K_EEPROM_MAGIC, ee->ee_magic);
-+	AR5K_EEPROM_READ(AR5K_EEPROM_PROTECT, ee->ee_protect);
-+	AR5K_EEPROM_READ(AR5K_EEPROM_REG_DOMAIN, ee->ee_regdomain);
-+	AR5K_EEPROM_READ(AR5K_EEPROM_VERSION, ee->ee_version);
-+	AR5K_EEPROM_READ(AR5K_EEPROM_HDR, ee->ee_header);
-+
-+	/* Return if we have an old EEPROM */
-+	if (ee->ee_version < AR5K_EEPROM_VERSION_3_0)
-+		return 0;
-+
-+#ifdef notyet
-+	/*
-+	 * Validate the checksum of the EEPROM date. There are some
-+	 * devices with invalid EEPROMs.
-+	 */
-+	for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
-+		AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
-+		cksum ^= val;
-+	}
-+	if (cksum != AR5K_EEPROM_INFO_CKSUM) {
-+		AR5K_PRINTF("Invalid EEPROM checksum 0x%04x\n", cksum);
-+		return -EIO;
-+	}
-+#endif
-+
-+	AR5K_EEPROM_READ(AR5K_EEPROM_ANT_GAIN(ee->ee_version), ee->ee_ant_gain);
-+
-+	if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
-+		AR5K_EEPROM_READ(AR5K_EEPROM_MISC0, ee->ee_misc0);
-+		AR5K_EEPROM_READ(AR5K_EEPROM_MISC1, ee->ee_misc1);
-+	}
-+
-+	if (ee->ee_version < AR5K_EEPROM_VERSION_3_3) {
-+		AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
-+		ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
-+		ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
-+
-+		AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
-+		ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
-+		ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
-+	}
-+
-+	/*
-+	 * Get conformance test limit values
-+	 */
-+	offset = AR5K_EEPROM_CTL(ee->ee_version);
-+	ee->ee_ctls = 0;
-+
-+	for (i = 0; i < AR5K_EEPROM_N_CTLS(ee->ee_version); i++) {
-+		AR5K_EEPROM_READ(offset++, val);
-+
-+		if (((val >> 8) & 0xff) == 0)
-+			break;
-+
-+		ee->ee_ctl[i] = (val >> 8) & 0xff;
-+		ee->ee_ctls++;
-+
-+		if ((val & 0xff) == 0)
- 			break;
-+
-+		ee->ee_ctl[i + 1] = val & 0xff;
-+		ee->ee_ctls++;
-+	}
-+
-+	/*
-+	 * Get values for 802.11a (5GHz)
-+	 */
-+	mode = AR5K_EEPROM_MODE_11A;
-+
-+	ee->ee_turbo_max_power[mode] =
-+	    AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
-+
-+	offset = AR5K_EEPROM_MODES_11A(ee->ee_version);
-+
-+	ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	AR5K_EEPROM_READ(offset++, val);
-+	ee->ee_adc_desired_size[mode]	= (int8_t)((val >> 8) & 0xff);
-+	ee->ee_ob[mode][3]		= (val >> 5) & 0x7;
-+	ee->ee_db[mode][3]		= (val >> 2) & 0x7;
-+	ee->ee_ob[mode][2]		= (val << 1) & 0x7;
-+
-+	AR5K_EEPROM_READ(offset++, val);
-+	ee->ee_ob[mode][2]		|= (val >> 15) & 0x1;
-+	ee->ee_db[mode][2]		= (val >> 12) & 0x7;
-+	ee->ee_ob[mode][1]		= (val >> 9) & 0x7;
-+	ee->ee_db[mode][1]		= (val >> 6) & 0x7;
-+	ee->ee_ob[mode][0]		= (val >> 3) & 0x7;
-+	ee->ee_db[mode][0]		= val & 0x7;
-+
-+	ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1) {
-+		AR5K_EEPROM_READ(offset++, val);
-+		ee->ee_margin_tx_rx[mode] = val & 0x3f;
-+	}
-+
-+	/*
-+	 * Get values for 802.11b (2.4GHz)
-+	 */
-+	mode = AR5K_EEPROM_MODE_11B;
-+	offset = AR5K_EEPROM_MODES_11B(ee->ee_version);
-+
-+	ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	AR5K_EEPROM_READ(offset++, val);
-+	ee->ee_adc_desired_size[mode]	= (int8_t)((val >> 8) & 0xff);
-+	ee->ee_ob[mode][1]		= (val >> 4) & 0x7;
-+	ee->ee_db[mode][1]		= val & 0x7;
-+
-+	ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
-+		AR5K_EEPROM_READ(offset++, val);
-+
-+		ee->ee_cal_piers_b = 0;
-+
-+		ee->ee_pwr_cal_b[0].freq =
-+			ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-+		if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
-+			ee->ee_cal_piers_b++;
-+
-+		ee->ee_pwr_cal_b[1].freq =
-+			ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
-+		if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
-+			ee->ee_cal_piers_b++;
-+
-+		AR5K_EEPROM_READ(offset++, val);
-+		ee->ee_pwr_cal_b[2].freq =
-+			ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-+		if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
-+			ee->ee_cal_piers_b++;
-+	}
-+
-+	if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1)
-+		ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
-+
-+	/*
-+	 * Get values for 802.11g (2.4GHz)
-+	 */
-+	mode = AR5K_EEPROM_MODE_11G;
-+	offset = AR5K_EEPROM_MODES_11G(ee->ee_version);
-+
-+	ret = ath5k_eeprom_read_ants(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	AR5K_EEPROM_READ(offset++, val);
-+	ee->ee_adc_desired_size[mode]	= (signed short int)((val >> 8) & 0xff);
-+	ee->ee_ob[mode][1]		= (val >> 4) & 0x7;
-+	ee->ee_db[mode][1]		= val & 0x7;
-+
-+	ret = ath5k_eeprom_read_modes(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) {
-+		AR5K_EEPROM_READ(offset++, val);
-+
-+		ee->ee_cal_piers_g = 0;
-+
-+		ee->ee_pwr_cal_g[0].freq =
-+			ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-+		if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
-+			ee->ee_cal_piers_g++;
-+
-+		ee->ee_pwr_cal_g[1].freq =
-+			ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
-+		if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
-+			ee->ee_cal_piers_g++;
-+
-+		AR5K_EEPROM_READ(offset++, val);
-+		ee->ee_turbo_max_power[mode] = val & 0x7f;
-+		ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
-+
-+		AR5K_EEPROM_READ(offset++, val);
-+		ee->ee_pwr_cal_g[2].freq =
-+			ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-+		if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
-+			ee->ee_cal_piers_g++;
-+
-+		if (ee->ee_version >= AR5K_EEPROM_VERSION_4_1)
-+			ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
-+
-+		AR5K_EEPROM_READ(offset++, val);
-+		ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
-+		ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
-+
-+		if (ee->ee_version >= AR5K_EEPROM_VERSION_4_2) {
-+			AR5K_EEPROM_READ(offset++, val);
-+			ee->ee_cck_ofdm_gain_delta = val & 0xff;
- 		}
- 	}
- 
--	return (name);
-+	/*
-+	 * Read 5GHz EEPROM channels
-+	 */
-+	offset = AR5K_EEPROM_CHANNELS_5GHZ(ee->ee_version);
-+	ee->ee_cal_piers_a = 0;
-+	for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
-+		AR5K_EEPROM_READ(offset++, val);
-+
-+		if ((val & 0xff) == 0)
-+			break;
-+
-+		ee->ee_pwr_cal_a[i].freq =
-+			ath5k_eeprom_bin2freq(ee, val & 0xff, AR5K_EEPROM_MODE_11A);
-+		ee->ee_cal_piers_a++;
-+
-+		if (((val >> 8) & 0xff) == 0)
-+			break;
-+
-+		ee->ee_pwr_cal_a[++i].freq =
-+			ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, AR5K_EEPROM_MODE_11A);
-+		ee->ee_cal_piers_a++;
-+
-+	}
-+
-+	/*
-+	 * Read power calibration info
-+	 */
-+	mode = AR5K_EEPROM_MODE_11A;
-+	ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	mode = AR5K_EEPROM_MODE_11B;
-+	ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	mode = AR5K_EEPROM_MODE_11G;
-+	ret = ath5k_eeprom_read_pcal_info(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+
-+	/*
-+	 * Read per rate target power info
-+	 */
-+	offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) + AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
-+	mode = AR5K_EEPROM_MODE_11A;
-+	ret = ath5k_eeprom_read_target_rate_pwr_info(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) + AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
-+	mode = AR5K_EEPROM_MODE_11B;
-+	ret = ath5k_eeprom_read_target_rate_pwr_info(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) + AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
-+	mode = AR5K_EEPROM_MODE_11G;
-+	ret = ath5k_eeprom_read_target_rate_pwr_info(mem, mac_version, ee, &offset, mode);
-+	if (ret)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static const char *ath5k_hw_get_mac_name(u_int8_t val)
-+{
-+	static char name[16];
-+	unsigned int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(ath5k_mac_names); i++) {
-+		if (val <= ath5k_mac_names[i].sr_val)
-+			break;
-+	}
-+
-+	if (val == ath5k_mac_names[i].sr_val)
-+		return ath5k_mac_names[i].sr_name;
-+
-+	snprintf(name, sizeof(name), "%s+", ath5k_mac_names[i - 1].sr_name);
-+	return name;
-+}
-+
-+static const char *ath5k_hw_get_phy_name(u_int8_t val)
-+{
-+	const char *name = "?????";
-+	unsigned int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(ath5k_phy_names); i++) {
-+		if (val < ath5k_phy_names[i + 1].sr_val) {
-+			name = ath5k_phy_names[i].sr_name;
-+			break;
-+		}
-+	}
-+
-+	return name;
- }
- 
- /* returns -1 on unknown name */
- static int eeprom_name2addr(const char *name)
- {
--	int i;
-+	unsigned int i;
-+
- 	if (!name || !name[0])
- 		return -1;
--	for (i = 0; i < eeprom_addr_len; i++)
-+	for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
- 		if (!strcmp(name, eeprom_addr[i].name))
- 			return eeprom_addr[i].addr;
- 	return -1;
--}				/* eeprom_name2addr */
-+}
- 
- /* returns "<unknown>" on unknown address */
- static const char *eeprom_addr2name(int addr)
- {
--	int i;
--	for (i = 0; i < eeprom_addr_len; i++)
-+	unsigned int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
- 		if (eeprom_addr[i].addr == addr)
- 			return eeprom_addr[i].name;
- 	return "<unknown>";
--}				/* eeprom_addr2name */
-+}
- 
--static int
--do_write_pairs(int anr, int argc, char **argv, unsigned char *mem,
--	       int mac_version)
-+static int do_write_pairs(int anr, int argc, char **argv, unsigned char *mem,
-+			  int mac_version)
- {
- #define MAX_NR_WRITES 16
- 	struct {
-@@ -635,7 +1422,7 @@ do_write_pairs(int anr, int argc, char *
- 		}
- 		anr++;
- 		i++;
--	}			/* while (anr < (argc-1)) */
-+	}
- 
- 	if (!(wr_ops_len = i)) {
- 		err("no (addr,val) pairs given");
-@@ -702,20 +1489,22 @@ do_write_pairs(int anr, int argc, char *
- 	}
- 
- 	return errors ? 11 : 0;
--}				/* do_write_pairs */
-+}
- 
- static void usage(const char *n)
- {
--	int i;
-+	unsigned int i;
- 
--	fprintf(stderr, "%s [-w [-g N:M]] [-v] [-f] [-d] <base_address> "
-+	fprintf(stderr, "%s [-w [-g N:M]] [-v] [-f] [-d] [-R addr] [-W addr val] <base_address> "
- 		"[<name1> <val1> [<name2> <val2> ...]]\n\n", n);
- 	fprintf(stderr,
- 		"-w      write values into EEPROM\n"
- 		"-g N:M  set GPIO N to level M (only used with -w)\n"
- 		"-v      verbose output\n"
- 		"-f      force; suppress question before writing\n"
--		"-d      dump eeprom (file 'ath-eeprom-dump.bin' and screen)\n"
-+		"-d      dump EEPROM (file 'ath-eeprom-dump.bin' and screen)\n"
-+		"-R <addr>       read register at <addr> (hex)\n"
-+		"-W <addr> <val> write <val> (hex) into register at <addr> (hex)\n"
- 		"<base_address>  device base address (see lspci output)\n\n");
- 
- 	fprintf(stderr,
-@@ -725,8 +1514,8 @@ static void usage(const char *n)
- 		"  %s -w <base_address> regdomain N\n\n"
- 		"- set a PCI id field to value N:\n"
- 		"  %s -w <base_address> <field> N\n"
--		"  where <field> is on of:\n    ", n, n, n);
--	for (i = 0; i < eeprom_addr_len; i++)
-+		"  where <field> is one of:\n    ", n, n, n);
-+	for (i = 0; i < ARRAY_SIZE(eeprom_addr); i++)
- 		fprintf(stderr, " %s", eeprom_addr[i].name);
- 	fprintf(stderr, "\n\n");
- 	fprintf(stderr,
-@@ -739,19 +1528,457 @@ static void usage(const char *n)
- 		"unlawful radio transmissions!\n\n");
- }
- 
-+static void dump_capabilities(struct ath5k_eeprom_info *ee)
-+{
-+	u_int8_t has_a, has_b, has_g, has_rfkill, turbog_dis, turboa_dis;
-+	u_int8_t xr2_dis, xr5_dis, has_crystal;
-+
-+	has_a = AR5K_EEPROM_HDR_11A(ee->ee_header);
-+	has_b = AR5K_EEPROM_HDR_11B(ee->ee_header);
-+	has_g = AR5K_EEPROM_HDR_11G(ee->ee_header);
-+	has_rfkill = AR5K_EEPROM_HDR_RFKILL(ee->ee_header);
-+	has_crystal = AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1);
-+	turbog_dis = AR5K_EEPROM_HDR_T_2GHZ_DIS(ee->ee_header);
-+	turboa_dis = AR5K_EEPROM_HDR_T_5GHZ_DIS(ee->ee_header);
-+	xr2_dis = AR5K_EEPROM_HDR_XR2_DIS(ee->ee_misc0);
-+	xr5_dis = AR5K_EEPROM_HDR_XR5_DIS(ee->ee_misc0);
-+
-+	printf("|================= Capabilities ================|\n");
-+
-+	printf("| 802.11a Support: ");
-+	if (has_a)
-+		printf(" yes |");
-+	else
-+		printf(" no  |");
-+
-+	printf(" Turbo-A disabled:");
-+	if (turboa_dis)
-+		printf(" yes |\n");
-+	else
-+		printf(" no  |\n");
-+
-+	printf("| 802.11b Support: ");
-+	if (has_b)
-+		printf(" yes |");
-+	else
-+		printf(" no  |");
-+
-+	printf(" Turbo-G disabled:");
-+	if (turbog_dis)
-+		printf(" yes |\n");
-+	else
-+		printf(" no  |\n");
-+
-+	printf("| 802.11g Support: ");
-+	if (has_g)
-+		printf(" yes |");
-+	else
-+		printf(" no  |");
-+
-+	printf(" 2GHz XR disabled:");
-+	if (xr2_dis)
-+		printf(" yes |\n");
-+	else
-+		printf(" no  |\n");
-+
-+	printf("| RFKill  Support: ");
-+	if (has_rfkill)
-+		printf(" yes |");
-+	else
-+		printf(" no  |");
-+
-+	printf(" 5GHz XR disabled:");
-+	if (xr5_dis)
-+		printf(" yes |\n");
-+	else
-+		printf(" no  |\n");
-+
-+	if (has_crystal != 2) {
-+		printf("| 32kHz   Crystal: ");
-+		if (has_crystal)
-+			printf(" yes |");
-+		else
-+			printf(" no  |");
-+
-+		printf("                       |\n");
-+	}
-+
-+	printf("\\===============================================/\n");
-+}
-+
-+static void dump_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
-+{
-+	int i;
-+
-+	printf("|=========================================================|\n");
-+	printf("| I power:              0x%02x |", ee->ee_i_cal[mode]);
-+	printf(" Q power:              0x%02x |\n", ee->ee_q_cal[mode]);
-+	printf("| Use fixed bias:       0x%02x |", ee->ee_fixed_bias[mode]);
-+	printf(" Max turbo power:      0x%02x |\n", ee->ee_turbo_max_power[mode]);
-+	printf("| Max XR power:         0x%02x |", ee->ee_xr_power[mode]);
-+	printf(" Switch Settling Time: 0x%02x |\n", ee->ee_switch_settling[mode]);
-+	printf("| Tx/Rx attenuation:    0x%02x |", ee->ee_ant_tx_rx[mode]);
-+	printf(" TX end to XLNA On:    0x%02x |\n", ee->ee_tx_end2xlna_enable[mode]);
-+	printf("| TX end to XPA Off:    0x%02x |", ee->ee_tx_end2xpa_disable[mode]);
-+	printf(" TX end to XPA On:     0x%02x |\n", ee->ee_tx_frm2xpa_enable[mode]);
-+	printf("| 62db Threshold:       0x%02x |", ee->ee_thr_62[mode]);
-+	printf(" XLNA gain:            0x%02x |\n", ee->ee_xlna_gain[mode]);
-+	printf("| XPD:                  0x%02x |", ee->ee_xpd[mode]);
-+	printf(" XPD gain:             0x%02x |\n", ee->ee_x_gain[mode]);
-+	printf("| I gain:               0x%02x |", ee->ee_i_gain[mode]);
-+	printf(" Tx/Rx margin:         0x%02x |\n", ee->ee_margin_tx_rx[mode]);
-+	printf("| False detect backoff: 0x%02x |", ee->ee_false_detect[mode]);
-+	printf(" Noise Floor Threshold: %3d |\n", ee->ee_noise_floor_thr[mode]);
-+	printf("| ADC desired size:      %3d |", ee->ee_adc_desired_size[mode]);
-+	printf(" PGA desired size:      %3d |\n", ee->ee_pga_desired_size[mode]);
-+	printf("|=========================================================|\n");
-+	for (i = 0; i < AR5K_EEPROM_N_PCDAC; i++) {
-+		printf("| Antenna control  %2i:  0x%02x |", i, ee->ee_ant_control[mode][i]);
-+		i++;
-+		printf(" Antenna control  %2i:  0x%02x |\n", i, ee->ee_ant_control[mode][i]);
-+	}
-+	printf("|=========================================================|\n");
-+	for (i = 0; i < AR5K_EEPROM_N_OBDB; i++) {
-+		printf("| Octave Band %i:          %2i |", i, ee->ee_ob[mode][i]);
-+		printf(" db %i:                   %2i |\n", i, ee->ee_db[mode][i]);
-+	}
-+	printf("\\=========================================================/\n");
-+}
-+
-+static void dump_power_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
-+{
-+	struct ath5k_chan_pcal_info *chan_pcal_info;
-+	u_int16_t cal_piers;
-+	int i, c;
-+
-+	switch (mode) {
-+	case AR5K_EEPROM_MODE_11A:
-+		chan_pcal_info = ee->ee_pwr_cal_a;
-+		cal_piers = ee->ee_cal_piers_a;
-+		break;
-+	case AR5K_EEPROM_MODE_11B:
-+		chan_pcal_info = ee->ee_pwr_cal_b;
-+		cal_piers = ee->ee_cal_piers_b;
-+		break;
-+	case AR5K_EEPROM_MODE_11G:
-+		chan_pcal_info = ee->ee_pwr_cal_g;
-+		cal_piers = ee->ee_cal_piers_g;
-+		break;
-+	default:
-+		return;
-+	}
-+
-+	printf("/=================== Per channel power calibration ====================\\\n");
-+	printf("| Freq | pwr_0 | pwr_1 | pwr_2 | pwr_3 |pwrx3_0|pwrx3_1|pwrx3_2|max_pwr|\n");
-+	printf("|      | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac |       |\n");
-+
-+	for (i = 0; i < cal_piers; i++) {
-+		char buf[16];
-+
-+		printf("|======|=======|=======|=======|=======|=======|=======|=======|=======|\n");
-+		printf("| %4i |", chan_pcal_info[i].freq);
-+		for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
-+			printf(" %2i.%02i |", chan_pcal_info[i].pwr_x0[c] / 4,
-+			       chan_pcal_info[i].pwr_x0[c] % 4);
-+		}
-+		for (c = 0; c < AR5K_EEPROM_N_XPD3_POINTS; c++) {
-+			printf(" %2i.%02i |", chan_pcal_info[i].pwr_x3[c] / 4,
-+			       chan_pcal_info[i].pwr_x3[c] % 4);
-+		}
-+		printf(" %2i.%02i |\n", chan_pcal_info[i].max_pwr / 4,
-+		       chan_pcal_info[i].max_pwr % 4);
-+
-+		printf("|      |");
-+		for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
-+			snprintf(buf, sizeof(buf), "[%i]",
-+				 chan_pcal_info[i].pcdac_x0[c]);
-+			printf("%6s |", buf);
-+		}
-+		for (c = 0; c < AR5K_EEPROM_N_XPD3_POINTS; c++) {
-+			snprintf(buf, sizeof(buf), "[%i]",
-+				 chan_pcal_info[i].pcdac_x3[c]);
-+			printf("%6s |", buf);
-+		}
-+		printf("       |\n");
-+
-+	}
-+	printf("\\======================================================================/\n");
-+}
-+
-+static void dump_rate_calinfo_for_mode(int mode, struct ath5k_eeprom_info *ee)
-+{
-+	int i;
-+	struct ath5k_rate_pcal_info *rate_pcal_info;
-+	u_int16_t rate_target_pwr_num;
-+
-+	switch (mode) {
-+	case AR5K_EEPROM_MODE_11A:
-+		rate_pcal_info = ee->ee_rate_tpwr_a;
-+		rate_target_pwr_num = ee->ee_rate_target_pwr_num_a;
-+		break;
-+	case AR5K_EEPROM_MODE_11B:
-+		rate_pcal_info = ee->ee_rate_tpwr_b;
-+		rate_target_pwr_num = ee->ee_rate_target_pwr_num_b;
-+		break;
-+	case AR5K_EEPROM_MODE_11G:
-+		rate_pcal_info = ee->ee_rate_tpwr_g;
-+		rate_target_pwr_num = ee->ee_rate_target_pwr_num_g;
-+		break;
-+	default:
-+		return;
-+	}
-+
-+	printf("/============== Per rate power calibration ===========\\\n");
-+	if (mode == AR5K_EEPROM_MODE_11B)
-+		printf("| Freq |   1Mbit/s  | 2Mbit/s  | 5.5Mbit/s | 11Mbit/s |\n");
-+	else
-+		printf("| Freq | 6-24Mbit/s | 36Mbit/s |  48Mbit/s | 54Mbit/s |\n");
-+
-+	for (i = 0; i < rate_target_pwr_num; i++) {
-+
-+		printf("|======|============|==========|===========|==========|\n");
-+		printf("| %4i |", rate_pcal_info[i].freq);
-+		printf("    %2i.%02i   |",rate_pcal_info[i].target_power_6to24 /2,
-+					rate_pcal_info[i].target_power_6to24 % 2);
-+		printf("  %2i.%02i   |",rate_pcal_info[i].target_power_36 /2,
-+					rate_pcal_info[i].target_power_36 % 2);
-+		printf("   %2i.%02i   |",rate_pcal_info[i].target_power_48 /2,
-+					rate_pcal_info[i].target_power_48 % 2);
-+		printf("  %2i.%02i   |\n",rate_pcal_info[i].target_power_54 /2,
-+					rate_pcal_info[i].target_power_54 % 2);
-+	}
-+	printf("\\=====================================================/\n");
-+}
-+
-+static u_int32_t extend_tu(u_int32_t base_tu, u_int32_t val, u_int32_t mask)
-+{
-+	u_int32_t result;
-+
-+	result = (base_tu & ~mask) | (val & mask);
-+	if ((base_tu & mask) > (val & mask))
-+		result += mask + 1;
-+	return result;
-+}
-+
-+static void dump_timers_register(void *mem, u_int16_t mac_version)
-+{
-+#define AR5K_TIMER0_5210		0x802c	/* next TBTT */
-+#define AR5K_TIMER0_5211		0x8028
-+#define AR5K_TIMER0			(mac_version == AR5K_SREV_MAC_AR5210 ? \
-+					AR5K_TIMER0_5210 : AR5K_TIMER0_5211)
-+
-+#define AR5K_TIMER1_5210		0x8030	/* next DMA beacon */
-+#define AR5K_TIMER1_5211		0x802c
-+#define AR5K_TIMER1			(mac_version == AR5K_SREV_MAC_AR5210 ? \
-+					AR5K_TIMER1_5210 : AR5K_TIMER1_5211)
-+
-+#define AR5K_TIMER2_5210		0x8034	/* next SWBA interrupt */
-+#define AR5K_TIMER2_5211		0x8030
-+#define AR5K_TIMER2			(mac_version == AR5K_SREV_MAC_AR5210 ? \
-+					AR5K_TIMER2_5210 : AR5K_TIMER2_5211)
-+
-+#define AR5K_TIMER3_5210		0x8038	/* next ATIM window */
-+#define AR5K_TIMER3_5211		0x8034
-+#define AR5K_TIMER3			(mac_version == AR5K_SREV_MAC_AR5210 ? \
-+					AR5K_TIMER3_5210 : AR5K_TIMER3_5211)
-+
-+#define AR5K_TSF_L32_5210		0x806c	/* TSF (lower 32 bits) */
-+#define AR5K_TSF_L32_5211		0x804c
-+#define AR5K_TSF_L32			(mac_version == AR5K_SREV_MAC_AR5210 ? \
-+					AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
-+
-+#define AR5K_TSF_U32_5210		0x8070
-+#define AR5K_TSF_U32_5211		0x8050
-+#define AR5K_TSF_U32			(mac_version == AR5K_SREV_MAC_AR5210 ? \
-+					AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
-+
-+#define AR5K_BEACON_5210		0x8024
-+#define AR5K_BEACON_5211		0x8020
-+#define AR5K_BEACON			(mac_version == AR5K_SREV_MAC_AR5210 ? \
-+					AR5K_BEACON_5210 : AR5K_BEACON_5211)
-+
-+#define AR5K_LAST_TSTP			0x8080
-+
-+	const int timer_mask = 0xffff;
-+
-+	u_int32_t timer0, timer1, timer2, timer3, now_tu;
-+	u_int32_t timer0_tu, timer1_tu, timer2_tu, timer3_tu;
-+	u_int64_t now_tsf;
-+
-+	timer0 = AR5K_REG_READ(AR5K_TIMER0);		/* 0x0000ffff */
-+	timer1 = AR5K_REG_READ(AR5K_TIMER1_5211);	/* 0x0007ffff */
-+	timer2 = AR5K_REG_READ(AR5K_TIMER2_5211);	/* 0x?1ffffff */
-+	timer3 = AR5K_REG_READ(AR5K_TIMER3_5211);	/* 0x0000ffff */
-+
-+	now_tsf = ((u_int64_t)AR5K_REG_READ(AR5K_TSF_U32_5211) << 32)
-+		| (u_int64_t)AR5K_REG_READ(AR5K_TSF_L32_5211);
-+
-+	now_tu = now_tsf >> 10;
-+
-+	timer0_tu = extend_tu(now_tu, timer0, 0xffff);
-+	printf("TIMER0: 0x%08x, TBTT: %5u, TU: 0x%08x\n", timer0,
-+	       timer0 & timer_mask, timer0_tu);
-+	timer1_tu = extend_tu(now_tu, timer1 >> 3, 0x7ffff >> 3);
-+	printf("TIMER1: 0x%08x, DMAb: %5u, TU: 0x%08x (%+d)\n", timer1,
-+	       (timer1 >> 3) & timer_mask, timer1_tu, timer1_tu - timer0_tu);
-+	timer2_tu = extend_tu(now_tu, timer2 >> 3, 0x1ffffff >> 3);
-+	printf("TIMER2: 0x%08x, SWBA: %5u, TU: 0x%08x (%+d)\n", timer2,
-+	       (timer2 >> 3) & timer_mask, timer2_tu, timer2_tu - timer0_tu);
-+	timer3_tu = extend_tu(now_tu, timer3, 0xffff);
-+	printf("TIMER3: 0x%08x, ATIM: %5u, TU: 0x%08x (%+d)\n", timer3,
-+	       timer3 & timer_mask, timer3_tu, timer3_tu - timer0_tu);
-+	printf("TSF: 0x%016llx, TSFTU: %5u, TU: 0x%08x\n",
-+	       (unsigned long long)now_tsf, now_tu & timer_mask, now_tu);
-+
-+	printf("BEACON: 0x%08x\n", AR5K_REG_READ(AR5K_BEACON));
-+	printf("LAST_TSTP: 0x%08x\n", AR5K_REG_READ(AR5K_LAST_TSTP));
-+}
-+
-+#define AR5K_KEYTABLE_0_5210		0x9000
-+#define AR5K_KEYTABLE_0_5211		0x8800
-+#define AR5K_KEYTABLE_0			(mac_version == AR5K_SREV_MAC_AR5210 ? \
-+					AR5K_KEYTABLE_0_5210 : \
-+					AR5K_KEYTABLE_0_5211)
-+
-+#define AR5K_KEYTABLE(_n)		(AR5K_KEYTABLE_0_5211 + ((_n) << 5))
-+#define AR5K_KEYTABLE_OFF(_n, x)	(AR5K_KEYTABLE(_n) + ((x) << 2))
-+#define AR5K_KEYTABLE_VALID		0x00008000
-+
-+#define AR5K_KEYTABLE_SIZE_5210		64
-+#define AR5K_KEYTABLE_SIZE_5211		128
-+#define AR5K_KEYTABLE_SIZE		(mac_version == AR5K_SREV_MAC_AR5210 ? \
-+					AR5K_KEYTABLE_SIZE_5210 : \
-+					AR5K_KEYTABLE_SIZE_5211)
-+
-+static void keycache_dump(void *mem, u_int16_t mac_version)
-+{
-+	int i, keylen;
-+	u_int32_t val0, val1, val2, val3, val4, keytype, ant, mac0, mac1;
-+
-+	/* dump all 128 entries */
-+	printf("Dumping keycache entries...\n");
-+	for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) {
-+		mac1 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 7));
-+		if (mac1 & AR5K_KEYTABLE_VALID) {
-+			val0    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 0));
-+			val1    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 1));
-+			val2    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 2));
-+			val3    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 3));
-+			val4    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 4));
-+			keytype = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 5));
-+			ant = keytype & 8;
-+			keytype &= ~8;
-+			switch (keytype) {
-+			case 0: /* WEP40  */ keylen =  40 / 8; break;
-+			case 1: /* WEP104 */ keylen = 104 / 8; break;
-+			case 3: /* WEP128 */ keylen = 128 / 8; break;
-+			case 4: /* TKIP   */ keylen = 128 / 8; break;
-+			case 5: /* AES    */ keylen = 128 / 8; break;
-+			case 6: /* CCM    */ keylen = 128 / 8; break;
-+			default:             keylen = 0;       break;
-+			}
-+			mac0 = AR5K_REG_READ(AR5K_KEYTABLE_OFF(i, 6));
-+
-+			printf("[%3u] keytype %d [%s%s%s%s%s%s%s%s] mac %02x:%02x:%02x:%02x:%02x:%02x key:%08x-%08x-%08x-%08x-%08x\n",
-+			       i,
-+			       keytype,
-+			       keytype == 0 ? "WEP40 " : "",
-+			       keytype == 1 ? "WEP104" : "",
-+			       keytype == 3 ? "WEP128" : "",
-+			       keytype == 4 ? "TKIP  " : "",
-+			       keytype == 5 ? "AES   " : "",
-+			       keytype == 6 ? "CCM   " : "",
-+			       keytype == 7 ? "NULL  " : "",
-+			       ant     == 8 ? "+ANT"   : "",
-+			       ((mac0 <<  1) & 0xff),
-+			       ((mac0 >>  7) & 0xff),
-+			       ((mac0 >> 15) & 0xff),
-+			       ((mac0 >> 23) & 0xff),
-+			       ((mac1 <<  1) & 0xff) | (mac0 >> 31),
-+			       ((mac1 >>  7) & 0xff),
-+			       val0, val1, val2, val3, val4);
-+		}
-+	}
-+}
-+
-+/* copy key index (0) to key index (idx) */
-+
-+static void keycache_copy(void *mem, u_int16_t mac_version, int idx)
-+{
-+	u_int32_t val0, val1, val2, val3, val4, keytype, mac0, mac1;
-+
-+	printf("Copying keycache entry 0 to %d\n", idx);
-+	if (idx < 0 || idx >= AR5K_KEYTABLE_SIZE) {
-+		printf("invalid keycache index\n");
-+		return;
-+	}
-+
-+	val0    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 0));
-+	val1    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 1));
-+	val2    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 2));
-+	val3    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 3));
-+	val4    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 4));
-+	keytype = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 5));
-+	mac0    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 6));
-+	mac1    = AR5K_REG_READ(AR5K_KEYTABLE_OFF(0, 7));
-+
-+	AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 0), val0);
-+	AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 1), val1);
-+	AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 2), val2);
-+	AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 3), val3);
-+	AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 4), val4);
-+	AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 5), keytype);
-+	AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 6), mac0);
-+	AR5K_REG_WRITE(AR5K_KEYTABLE_OFF(idx, 7), mac1);
-+}
-+
-+static void sta_id0_id1_dump(void *mem)
-+{
-+#define AR5K_STA_ID0			0x8000
-+#define AR5K_STA_ID1			0x8004
-+#define AR5K_STA_ID1_AP                 0x00010000
-+#define AR5K_STA_ID1_ADHOC              0x00020000
-+#define AR5K_STA_ID1_NO_KEYSRCH		0x00080000
-+
-+	u_int32_t sta_id0, sta_id1;
-+
-+	sta_id0 = AR5K_REG_READ(AR5K_STA_ID0);
-+	sta_id1 = AR5K_REG_READ(AR5K_STA_ID1);
-+	printf("STA_ID0: %02x:%02x:%02x:%02x:%02x:%02x\n",
-+	       (sta_id0 >>  0) & 0xff,
-+	       (sta_id0 >>  8) & 0xff,
-+	       (sta_id0 >> 16) & 0xff,
-+	       (sta_id0 >> 24) & 0xff,
-+	       (sta_id1 >>  0) & 0xff,
-+	       (sta_id1 >>  8) & 0xff);
-+	printf("STA_ID1: 0x%08x, AP: %d, IBSS: %d, KeyCache Disable: %d\n",
-+	       sta_id1,
-+	       sta_id1 & AR5K_STA_ID1_AP ? 1 : 0,
-+	       sta_id1 & AR5K_STA_ID1_ADHOC ? 1 : 0,
-+	       sta_id1 & AR5K_STA_ID1_NO_KEYSRCH ? 1 : 0);
-+}
-+
- int
- CMD(athinfo)(int argc, char *argv[])
- {
--	u_int32_t dev_addr;
--	u_int16_t eeprom_header, srev, phy_rev_5ghz, phy_rev_2ghz;
--	u_int16_t eeprom_version, mac_version, regdomain, has_crystal, ee_magic;
--	u_int8_t error, has_a, has_b, has_g, has_rfkill, eeprom_size;
--	int byte_size = 0;
-+	unsigned long long dev_addr;
-+	u_int16_t srev, phy_rev_5ghz, phy_rev_2ghz, ee_magic;
-+	u_int8_t mac_version, mac_revision;
-+	u_int8_t error, eeprom_size, dev_type, eemap;
-+	struct ath5k_eeprom_info *ee;
-+	unsigned int byte_size = 0;
- 	void *mem;
- 	int fd;
--	int i, anr = 1;
-+	unsigned int i;
-+	int anr = 1;
- 	int do_write = 0;	/* default: read only */
- 	int do_dump = 0;
-+	int reg_read = 0;
-+	int reg_write = 0;
-+	unsigned int reg_write_val = 0;
-+	unsigned int timer_count = 1;
-+	int do_keycache_dump = 0;
-+	int keycache_copy_idx = 0;
- 
- 	struct {
- 		int valid;
-@@ -759,7 +1986,7 @@ CMD(athinfo)(int argc, char *argv[])
- 	} gpio_set[AR5K_NUM_GPIO];
- 	int nr_gpio_set = 0;
- 
--	for (i = 0; i < sizeof(gpio_set) / sizeof(gpio_set[0]); i++)
-+	for (i = 0; i < ARRAY_SIZE(gpio_set); i++)
- 		gpio_set[i].valid = 0;
- 
- 	if (argc < 2) {
-@@ -769,6 +1996,15 @@ CMD(athinfo)(int argc, char *argv[])
- 
- 	while (anr < argc && argv[anr][0] == '-') {
- 		switch (argv[anr][1]) {
-+		case 't':
-+			if (++anr < argc) {
-+				timer_count = atoi(argv[anr]);
-+				printf("timer_count:%d\n", timer_count);
-+			} else {
-+				usage(argv[0]);
-+				return 0;
-+			}
-+			break;
- 		case 'w':
- 			do_write = 1;
- 			break;
-@@ -777,7 +2013,7 @@ CMD(athinfo)(int argc, char *argv[])
- 			if (strlen(argv[anr]) != 3 || argv[anr][1] != ':' ||
- 			    argv[anr][0] < '0' || argv[anr][0] > '5' ||
- 			    (argv[anr][2] != '0' && argv[anr][2] != '1')) {
--				err("invalid gpio spec. %s", argv[anr]);
-+				err("invalid GPIO spec. %s", argv[anr]);
- 				return 2;
- 			}
- 			gpio_set[argv[anr][0] - '0'].valid = 1;
-@@ -797,6 +2033,25 @@ CMD(athinfo)(int argc, char *argv[])
- 			do_dump = 1;
- 			break;
- 
-+		case 'R':
-+			anr++;
-+			reg_read = strtoul(argv[anr], NULL, 16);
-+			break;
-+
-+		case 'W':
-+			anr++;
-+			reg_write = strtoul(argv[anr++], NULL, 16);
-+			reg_write_val = strtoul(argv[anr], NULL, 16);
-+			break;
-+
-+		case 'k':
-+			do_keycache_dump = 1;
-+			break;
-+
-+		case 'K':
-+			keycache_copy_idx = atoi(argv[++anr]);
-+			break;
-+
- 		case 'h':
- 			usage(argv[0]);
- 			return 0;
-@@ -805,10 +2060,10 @@ CMD(athinfo)(int argc, char *argv[])
- 		default:
- 			err("unknown option %s", argv[anr]);
- 			return 2;
--		}		/* switch (argv[anr][1]) */
-+		}
- 
- 		anr++;
--	}			/* while (anr < argc && ...) */
-+	}
- 
- 	if (anr >= argc) {
- 		err("missing device address");
-@@ -816,7 +2071,7 @@ CMD(athinfo)(int argc, char *argv[])
- 		return 3;
- 	}
- 
--	dev_addr = strtoul(argv[anr], NULL, 16);
-+	dev_addr = strtoull(argv[anr], NULL, 16);
- 
- 	fd = open("/dev/mem", O_RDWR);
- 	if (fd < 0) {
-@@ -828,7 +2083,7 @@ CMD(athinfo)(int argc, char *argv[])
- 		   MAP_SHARED | MAP_FILE, fd, dev_addr);
- 
- 	if (mem == MAP_FAILED) {
--		printf("Mmap of device at 0x%08X for 0x%X bytes failed - "
-+		printf("mmap of device at 0x%08llX for 0x%X bytes failed - "
- 		       "%s\n", dev_addr, AR5K_PCI_MEM_SIZE, strerror(errno));
- 		return -3;
- 	}
-@@ -856,10 +2111,31 @@ CMD(athinfo)(int argc, char *argv[])
- 	AR5K_REG_DISABLE_BITS(AR5K_PCICFG, AR5K_PCICFG_SPWR_DN);
- 	usleep(500);
- 
-+	if (reg_read) {
-+		printf("READ %04x = %08x\n", reg_read, AR5K_REG_READ(reg_read));
-+		return 0;
-+	}
-+
-+	if (reg_write) {
-+		printf("WRITE %04x = %08x\n", reg_write, reg_write_val);
-+		AR5K_REG_WRITE(reg_write, reg_write_val);
-+		return 0;
-+	}
-+
- 	srev = AR5K_REG_READ(AR5K_SREV);
--	mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER) << 4;
-+	if (srev >= 0x0100) {
-+		printf("MAC revision 0x%04x is not supported!\n", srev);
-+		return -1;
-+	}
-+	mac_version = srev & AR5K_SREV_VER;
-+	mac_revision = srev & AR5K_SREV_REV;
- 
--	/* Verify eeprom magic value first */
-+	printf(" -==Device Information==-\n");
-+
-+	printf("MAC Revision: %-5s (0x%02x)\n",
-+	       ath5k_hw_get_mac_name(mac_revision), mac_revision);
-+
-+	/* Verify EEPROM magic value first */
- 	error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_MAGIC, &ee_magic,
- 				     mac_version);
- 
-@@ -872,157 +2148,114 @@ CMD(athinfo)(int argc, char *argv[])
- 		printf("Warning: Invalid EEPROM Magic number!\n");
- 	}
- 
--	error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_HDR, &eeprom_header,
--				     mac_version);
--
--	if (error) {
--		printf("Unable to read EEPROM Header!\n");
--		return -1;
--	}
--
--	error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_VERSION, &eeprom_version,
--				     mac_version);
--
--	if (error) {
--		printf("Unable to read EEPROM version!\n");
-+	ee = calloc(sizeof(struct ath5k_eeprom_info), 1);
-+	if (!ee) {
-+		printf("Cannot allocate memory for EEPROM information\n");
- 		return -1;
- 	}
- 
--	error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_REG_DOMAIN, &regdomain,
--				     mac_version);
--
--	if (error) {
--		printf("Unable to read Regdomain!\n");
-+	if (ath5k_eeprom_init(mem, mac_version, ee)) {
-+		printf("EEPROM init failed\n");
- 		return -1;
- 	}
- 
--	if (eeprom_version >= 0x4000) {
--		error = ath5k_hw_eeprom_read(mem, AR5K_EEPROM_MISC0,
--					     &has_crystal, mac_version);
--
--		if (error) {
--			printf("Unable to read EEPROM Misc data!\n");
--			return -1;
--		}
--
--		has_crystal = AR5K_EEPROM_HAS32KHZCRYSTAL(has_crystal);
--	} else {
--		has_crystal = 2;
--	}
--
- 	eeprom_size = AR5K_REG_MS(AR5K_REG_READ(AR5K_PCICFG),
- 				  AR5K_PCICFG_EESIZE);
- 
--	has_a = AR5K_EEPROM_HDR_11A(eeprom_header);
--	has_b = AR5K_EEPROM_HDR_11B(eeprom_header);
--	has_g = AR5K_EEPROM_HDR_11G(eeprom_header);
--	has_rfkill = AR5K_EEPROM_HDR_RFKILL(eeprom_header);
-+	dev_type = AR5K_EEPROM_HDR_DEVICE(ee->ee_header);
-+	eemap = AR5K_EEPROM_EEMAP(ee->ee_misc0);
- 
--	if (has_a)
-+	/* 1 = ?? 2 = ?? 3 = card 4 = wmac */
-+	printf("Device type:  %1i\n", dev_type);
-+
-+	if (AR5K_EEPROM_HDR_11A(ee->ee_header))
- 		phy_rev_5ghz = ath5k_hw_radio_revision(mac_version, mem, 1);
- 	else
- 		phy_rev_5ghz = 0;
- 
--	if (has_b)
-+	if (AR5K_EEPROM_HDR_11B(ee->ee_header))
- 		phy_rev_2ghz = ath5k_hw_radio_revision(mac_version, mem, 0);
- 	else
- 		phy_rev_2ghz = 0;
- 
--	printf(" -==Device Information==-\n");
--
--	printf("MAC Version:  %-5s (0x%02x)\n",
--	       ath5k_hw_get_part_name(AR5K_VERSION_VER, mac_version),
--	       mac_version);
--
--	printf("MAC Revision: %-5s (0x%02x)\n",
--	       ath5k_hw_get_part_name(AR5K_VERSION_VER, srev), srev);
--
--	/* Single-chip PHY with a/b/g support */
--	if (has_b && !phy_rev_2ghz) {
--		printf("PHY Revision: %-5s (0x%02x)\n",
--		       ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_5ghz),
--		       phy_rev_5ghz);
--		phy_rev_5ghz = 0;
--	}
--
--	/* Single-chip PHY with b/g support */
--	if (!has_a) {
--		printf("PHY Revision: %-5s (0x%02x)\n",
--		       ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_2ghz),
--		       phy_rev_2ghz);
--		phy_rev_2ghz = 0;
--	}
--
--	/* Different chip for 5Ghz and 2Ghz */
- 	if (phy_rev_5ghz) {
--		printf("5Ghz PHY Revision: %-5s (0x%2x)\n",
--		       ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_5ghz),
--		       phy_rev_5ghz);
-+		printf("5GHz PHY Revision: %-5s (0x%02x)\n",
-+		       ath5k_hw_get_phy_name(phy_rev_5ghz), phy_rev_5ghz);
- 	}
- 	if (phy_rev_2ghz) {
--		printf("2Ghz PHY Revision: %-5s (0x%2x)\n",
--		       ath5k_hw_get_part_name(AR5K_VERSION_RAD, phy_rev_2ghz),
--		       phy_rev_2ghz);
-+		printf("2GHz PHY Revision: %-5s (0x%02x)\n",
-+		       ath5k_hw_get_phy_name(phy_rev_2ghz), phy_rev_2ghz);
- 	}
- 
--	printf(" -==EEPROM Information==-\n");
--
--	printf("EEPROM Version:     %x.%x\n",
--	       (eeprom_version & 0xF000) >> 12, eeprom_version & 0xFFF);
-+	printf("\n");
-+	printf("/============== EEPROM Information =============\\\n");
-+	printf("| EEPROM Version:   %1x.%1x |",
-+	       (ee->ee_version & 0xF000) >> 12, ee->ee_version & 0xFFF);
- 
--	printf("EEPROM Size: ");
-+	printf(" EEPROM Size: ");
- 
- 	if (eeprom_size == 0) {
--		printf("       4K\n");
--		byte_size = 4096;
-+		printf("  4 kbit |\n");
-+		byte_size = 4096 / 8;
- 	} else if (eeprom_size == 1) {
--		printf("       8K\n");
--		byte_size = 8192;
-+		printf("  8 kbit |\n");
-+		byte_size = 8192 / 8;
- 	} else if (eeprom_size == 2) {
--		printf("       16K\n");
--		byte_size = 16384;
-+		printf(" 16 kbit |\n");
-+		byte_size = 16384 / 8;
- 	} else
--		printf("       ??\n");
-+		printf(" unknown |\n");
- 
--	printf("Regulatory Domain:  0x%X\n", regdomain);
--
--	printf(" -==== Capabilities ====-\n");
--
--	printf("|  802.11a Support: ");
--	if (has_a)
--		printf("yes  |\n");
--	else
--		printf("no   |\n");
--
--	printf("|  802.11b Support: ");
--	if (has_b)
--		printf("yes  |\n");
--	else
--		printf("no   |\n");
-+	printf("| EEMAP:              %i |", eemap);
- 
--	printf("|  802.11g Support: ");
--	if (has_g)
--		printf("yes  |\n");
--	else
--		printf("no   |\n");
-+	printf(" Reg. Domain:     0x%02X |\n", ee->ee_regdomain);
- 
--	printf("|  RFKill  Support: ");
--	if (has_rfkill)
--		printf("yes  |\n");
--	else
--		printf("no   |\n");
-+	dump_capabilities(ee);
-+	printf("\n");
- 
--	if (has_crystal != 2) {
--		printf("|  32KHz   Crystal: ");
--		if (has_crystal)
--			printf("yes  |\n");
--		else
--			printf("no   |\n");
-+	printf("/=========================================================\\\n");
-+	printf("|          Calibration data common for all modes          |\n");
-+	printf("|=========================================================|\n");
-+	printf("|          CCK/OFDM gain delta:            %2i             |\n", ee->ee_cck_ofdm_gain_delta);
-+	printf("|          CCK/OFDM power delta:           %2i             |\n", ee->ee_cck_ofdm_power_delta);
-+	printf("|          Scaled CCK delta:               %2i             |\n", ee->ee_scaled_cck_delta);
-+	printf("|          2GHz Antenna gain:              %2i             |\n", AR5K_EEPROM_ANT_GAIN_2GHZ(ee->ee_ant_gain));
-+	printf("|          5GHz Antenna gain:              %2i             |\n", AR5K_EEPROM_ANT_GAIN_5GHZ(ee->ee_ant_gain));
-+	printf("|          Turbo 2W maximum dBm:           %2i             |\n", AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header));
-+	printf("|          Target power start:          0x%03x             |\n", AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1));
-+	printf("|          EAR Start:                   0x%03x             |\n", AR5K_EEPROM_EARSTART(ee->ee_misc0));
-+	printf("\\=========================================================/\n");
-+
-+	printf("\n");
-+	if (AR5K_EEPROM_HDR_11A(ee->ee_header)) {
-+		printf("/=========================================================\\\n");
-+		printf("|          Calibration data for 802.11a operation         |\n");
-+		dump_calinfo_for_mode(AR5K_EEPROM_MODE_11A, ee);
-+		dump_rate_calinfo_for_mode(AR5K_EEPROM_MODE_11A, ee);
-+		dump_power_calinfo_for_mode(AR5K_EEPROM_MODE_11A, ee);
-+		printf("\n");
-+	}
-+
-+	if (AR5K_EEPROM_HDR_11B(ee->ee_header)) {
-+		printf("/=========================================================\\\n");
-+		printf("|          Calibration data for 802.11b operation         |\n");
-+		dump_calinfo_for_mode(AR5K_EEPROM_MODE_11B, ee);
-+		dump_rate_calinfo_for_mode(AR5K_EEPROM_MODE_11B, ee);
-+		dump_power_calinfo_for_mode(AR5K_EEPROM_MODE_11B, ee);
-+		printf("\n");
-+	}
-+
-+	if (AR5K_EEPROM_HDR_11G(ee->ee_header)) {
-+		printf("/=========================================================\\\n");
-+		printf("|          Calibration data for 802.11g operation         |\n");
-+		dump_calinfo_for_mode(AR5K_EEPROM_MODE_11G, ee);
-+		dump_rate_calinfo_for_mode(AR5K_EEPROM_MODE_11G, ee);
-+		dump_power_calinfo_for_mode(AR5K_EEPROM_MODE_11G, ee);
-+		printf("\n");
- 	}
--	printf(" ========================\n");
- 
- 	/* print current GPIO settings */
--	printf("GPIO registers: CR %08x DO %08x DI %08x\n",
-+	printf("GPIO registers: CR 0x%08x, DO 0x%08x, DI 0x%08x\n",
- 	       AR5K_REG_READ(AR5K_GPIOCR), AR5K_REG_READ(AR5K_GPIODO),
- 	       AR5K_REG_READ(AR5K_GPIODI));
- 
-@@ -1030,18 +2263,18 @@ CMD(athinfo)(int argc, char *argv[])
- 		u_int16_t data;
- 		FILE *dumpfile = fopen("ath-eeprom-dump.bin", "w");
- 
--		printf("\nEEPROM dump (%d byte)\n", byte_size);
-+		printf("\nEEPROM dump (%d bytes)\n", byte_size);
- 		printf("==============================================");
--		for (i = 1; i <= (byte_size / 2); i++) {
-+		for (i = 0; i < byte_size / 2; i++) {
- 			error =
- 			    ath5k_hw_eeprom_read(mem, i, &data, mac_version);
- 			if (error) {
- 				printf("\nUnable to read at %04x\n", i);
- 				continue;
- 			}
--			if (!((i - 1) % 8))
--				printf("\n%04x:  ", i);
--			printf("%04x ", data);
-+			if (!(i % 8))
-+				printf("\n%04x: ", i);
-+			printf(" %04x", data);
- 			fwrite(&data, 2, 1, dumpfile);
- 		}
- 		printf("\n==============================================\n");
-@@ -1054,18 +2287,18 @@ CMD(athinfo)(int argc, char *argv[])
- 		u_int32_t old_cr = rcr, old_do = rdo;
- 		int rc;
- 
--		if (mac_version >= AR5K_SREV_VER_AR5213 && !nr_gpio_set) {
--			dbg("new MAC %x (>= AR5213) set gpio4 to low",
-+		if (mac_version >= AR5K_SREV_MAC_AR5213 && !nr_gpio_set) {
-+			dbg("new MAC %x (>= AR5213) set GPIO4 to low",
- 			    mac_version);
- 			gpio_set[4].valid = 1;
- 			gpio_set[4].value = 0;
- 		}
- 
--		/* set gpios */
-+		/* set GPIOs */
- 		dbg("old GPIO CR %08x DO %08x DI %08x",
- 		    rcr, rdo, AR5K_REG_READ(AR5K_GPIODI));
- 
--		for (i = 0; i < sizeof(gpio_set) / sizeof(gpio_set[0]); i++) {
-+		for (i = 0; i < ARRAY_SIZE(gpio_set); i++) {
- 			if (gpio_set[i].valid) {
- 				rcr |= AR5K_GPIOCR_OUT(i);	/* we use mode 3 */
- 				rcr &= ~AR5K_GPIOCR_INT_SEL(i);
-@@ -1111,5 +2344,17 @@ CMD(athinfo)(int argc, char *argv[])
- 
- 		return rc;
- 	}
-+
-+	sta_id0_id1_dump(mem);
-+
-+	for (i = 0; i < timer_count; i++)
-+		dump_timers_register(mem, mac_version);
-+
-+	if (do_keycache_dump)
-+		keycache_dump(mem, mac_version);
-+
-+	if (keycache_copy_idx > 0)
-+		keycache_copy(mem, mac_version, keycache_copy_idx);
-+
- 	return 0;
- }
diff --git a/package/madwifi/patches/408-changeset_r3337.patch b/package/madwifi/patches/408-changeset_r3337.patch
deleted file mode 100644
index 53e76a9e8a..0000000000
--- a/package/madwifi/patches/408-changeset_r3337.patch
+++ /dev/null
@@ -1,34 +0,0 @@
---- a/THANKS
-+++ b/THANKS
-@@ -129,6 +129,7 @@ Derek J Smithies
- jhansen
- Benoit Papillault
- Russell Harmon
-+Alessandro Erta
- 
- Apologies to anyone whose name was unintentionally left off.
- Please let us know if you think your name should be mentioned here!
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -3147,7 +3147,7 @@ ath_tx_startraw(struct net_device *dev,
- 	struct ath_softc *sc = dev->priv;
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ieee80211_phy_params *ph = (struct ieee80211_phy_params *)
--		(SKB_CB(skb) + sizeof(struct ieee80211_cb));
-+		(SKB_CB(skb) + 1); /* NB: SKB_CB casts to CB struct*. */
- 	const HAL_RATE_TABLE *rt;
- 	unsigned int pktlen, hdrlen, try0, power;
- 	HAL_PKT_TYPE atype;
---- a/net80211/ieee80211_monitor.c
-+++ b/net80211/ieee80211_monitor.c
-@@ -128,8 +128,8 @@ struct ar5212_openbsd_desc {
- void
- ieee80211_monitor_encap(struct ieee80211vap *vap, struct sk_buff *skb)
- {
--	struct ieee80211_phy_params *ph =
--		(struct ieee80211_phy_params *) (SKB_CB(skb) + sizeof(struct ieee80211_cb));
-+	struct ieee80211_phy_params *ph = (struct ieee80211_phy_params *)
-+		(SKB_CB(skb) + 1); /* NB: SKB_CB casts to CB struct*. */
- 	SKB_CB(skb)->flags = M_RAW;
- 	SKB_CB(skb)->ni = NULL;
- 	SKB_CB(skb)->next = NULL;
diff --git a/package/madwifi/patches/409-wext_compat.patch b/package/madwifi/patches/409-wext_compat.patch
deleted file mode 100644
index 449709232c..0000000000
--- a/package/madwifi/patches/409-wext_compat.patch
+++ /dev/null
@@ -1,133 +0,0 @@
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -73,6 +73,13 @@
- 	 (_vap)->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO)
- #define	RESCAN	1
- 
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-+#define IWE(func, ...) func(&iweinfo, __VA_ARGS__)
-+static struct iw_request_info iweinfo = { 0, 0 };
-+#else
-+#define IWE(func, ...) func(__VA_ARGS__)
-+#endif
-+
- static void
- pre_announced_chanswitch(struct net_device *dev, u_int32_t channel, u_int32_t tbtt);
- 
-@@ -1800,7 +1807,7 @@ giwscan_cb(void *arg, const struct ieee8
- 		IEEE80211_ADDR_COPY(iwe.u.ap_addr.sa_data, se->se_macaddr);
- 	else
- 		IEEE80211_ADDR_COPY(iwe.u.ap_addr.sa_data, se->se_bssid);
--	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
-+	current_ev = IWE(iwe_stream_add_event, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
- 
- 	/* We ran out of space in the buffer. */
- 	if (last_ev == current_ev)
-@@ -1811,7 +1818,7 @@ giwscan_cb(void *arg, const struct ieee8
- 	iwe.cmd = SIOCGIWESSID;
- 	iwe.u.data.flags = 1;
- 	iwe.u.data.length = se->se_ssid[1];
--	current_ev = iwe_stream_add_point(current_ev,
-+	current_ev = IWE(iwe_stream_add_point, current_ev,
- 		end_buf, &iwe, (char *) se->se_ssid+2);
- 
- 	/* We ran out of space in the buffer. */
-@@ -1824,7 +1831,7 @@ giwscan_cb(void *arg, const struct ieee8
- 		iwe.cmd = SIOCGIWMODE;
- 		iwe.u.mode = se->se_capinfo & IEEE80211_CAPINFO_ESS ?
- 			IW_MODE_MASTER : IW_MODE_ADHOC;
--		current_ev = iwe_stream_add_event(current_ev,
-+		current_ev = IWE(iwe_stream_add_event, current_ev,
- 			end_buf, &iwe, IW_EV_UINT_LEN);
- 
- 		/* We ran out of space in the buffer. */
-@@ -1837,7 +1844,7 @@ giwscan_cb(void *arg, const struct ieee8
- 	iwe.cmd = SIOCGIWFREQ;
- 	iwe.u.freq.m = se->se_chan->ic_freq * 100000;
- 	iwe.u.freq.e = 1;
--	current_ev = iwe_stream_add_event(current_ev,
-+	current_ev = IWE(iwe_stream_add_event, current_ev,
- 		end_buf, &iwe, IW_EV_FREQ_LEN);
- 
- 	/* We ran out of space in the buffer. */
-@@ -1848,7 +1855,7 @@ giwscan_cb(void *arg, const struct ieee8
- 	last_ev = current_ev;
- 	iwe.cmd = IWEVQUAL;
- 	set_quality(&iwe.u.qual, se->se_rssi, ATH_DEFAULT_NOISE);
--	current_ev = iwe_stream_add_event(current_ev,
-+	current_ev = IWE(iwe_stream_add_event, current_ev,
- 		end_buf, &iwe, IW_EV_QUAL_LEN);
- 
- 	/* We ran out of space in the buffer */
-@@ -1863,7 +1870,7 @@ giwscan_cb(void *arg, const struct ieee8
- 	else
- 		iwe.u.data.flags = IW_ENCODE_DISABLED;
- 	iwe.u.data.length = 0;
--	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
-+	current_ev = IWE(iwe_stream_add_point, current_ev, end_buf, &iwe, "");
- 
- 	/* We ran out of space in the buffer. */
- 	if (last_ev == current_ev)
-@@ -1878,7 +1885,7 @@ giwscan_cb(void *arg, const struct ieee8
- 		int r = se->se_rates[2 + j] & IEEE80211_RATE_VAL;
- 		if (r != 0) {
- 			iwe.u.bitrate.value = r * (1000000 / 2);
--			current_val = iwe_stream_add_value(current_ev,
-+			current_val = IWE(iwe_stream_add_value, current_ev,
- 				current_val, end_buf, &iwe,
- 				IW_EV_PARAM_LEN);
- 		}
-@@ -1887,7 +1894,7 @@ giwscan_cb(void *arg, const struct ieee8
- 		int r = se->se_xrates[2+j] & IEEE80211_RATE_VAL;
- 		if (r != 0) {
- 			iwe.u.bitrate.value = r * (1000000 / 2);
--			current_val = iwe_stream_add_value(current_ev,
-+			current_val = IWE(iwe_stream_add_value, current_ev,
- 				current_val, end_buf, &iwe,
- 				IW_EV_PARAM_LEN);
- 		}
-@@ -1906,7 +1913,7 @@ giwscan_cb(void *arg, const struct ieee8
- 	iwe.cmd = IWEVCUSTOM;
- 	snprintf(buf, sizeof(buf), "bcn_int=%d", se->se_intval);
- 	iwe.u.data.length = strlen(buf);
--	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
-+	current_ev = IWE(iwe_stream_add_point, current_ev, end_buf, &iwe, buf);
- 
- 	/* We ran out of space in the buffer. */
- 	if (last_ev == current_ev)
-@@ -1930,7 +1937,7 @@ giwscan_cb(void *arg, const struct ieee8
- 				rsn_leader, sizeof(rsn_leader) - 1);
- #endif
- 		if (iwe.u.data.length != 0) {
--			current_ev = iwe_stream_add_point(current_ev, end_buf,
-+			current_ev = IWE(iwe_stream_add_point, current_ev, end_buf,
- 				&iwe, buf);
- 
- 			/* We ran out of space in the buffer */
-@@ -1956,7 +1963,7 @@ giwscan_cb(void *arg, const struct ieee8
- 			wpa_leader, sizeof(wpa_leader) - 1);
- #endif
- 		if (iwe.u.data.length != 0) {
--			current_ev = iwe_stream_add_point(current_ev, end_buf,
-+			current_ev = IWE(iwe_stream_add_point, current_ev, end_buf,
- 				&iwe, buf);
- 
- 			/* We ran out of space in the buffer. */
-@@ -1975,7 +1982,7 @@ giwscan_cb(void *arg, const struct ieee8
- 			se->se_wme_ie, se->se_wme_ie[1] + 2,
- 			wme_leader, sizeof(wme_leader) - 1);
- 		if (iwe.u.data.length != 0) {
--			current_ev = iwe_stream_add_point(current_ev, end_buf,
-+			current_ev = IWE(iwe_stream_add_point, current_ev, end_buf,
- 				&iwe, buf);
- 
- 			/* We ran out of space in the buffer. */
-@@ -1993,7 +2000,7 @@ giwscan_cb(void *arg, const struct ieee8
- 			se->se_ath_ie, se->se_ath_ie[1] + 2,
- 			ath_leader, sizeof(ath_leader) - 1);
- 		if (iwe.u.data.length != 0) {
--			current_ev = iwe_stream_add_point(current_ev, end_buf,
-+			current_ev = IWE(iwe_stream_add_point, current_ev, end_buf,
- 				&iwe, buf);
- 
- 			/* We ran out of space in the buffer. */
diff --git a/package/madwifi/patches/410-ar231x_2.6.28.patch b/package/madwifi/patches/410-ar231x_2.6.28.patch
deleted file mode 100644
index 30d1c56a4c..0000000000
--- a/package/madwifi/patches/410-ar231x_2.6.28.patch
+++ /dev/null
@@ -1,281 +0,0 @@
---- a/ath/if_ath_ahb.c
-+++ b/ath/if_ath_ahb.c
-@@ -33,20 +33,15 @@
- #include "if_ath_ahb.h"
- #include "ah_soc.h"
- 
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
--#error "Kernel versions older than 2.6.19 are not supported!"
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
-+#include <ar231x_platform.h>
- #endif
- 
- struct ath_ahb_softc {
- 	struct ath_softc	aps_sc;
--#ifdef CONFIG_PM
--	u32 aps_pmstate[16];
--#endif
-+	struct ar531x_config aps_config;
- };
- 
--static struct ath_ahb_softc *sclist[2] = {NULL, NULL};
--static u_int8_t num_activesc = 0;
--
- /*
-  * Module glue.
-  */
-@@ -101,13 +96,13 @@ ahb_enable_wmac(u_int16_t devid, u_int16
- 		while (REG_READ(AR5315_PCI_MAC_PCICFG) & AR5315_PCI_MAC_PCICFG_SPWR_DN);
- 	} else {
- 		switch (wlanNum) {
--		case AR531X_WLAN0_NUM:
-+		case 0:
- 			reset = (AR531X_RESET_WLAN0 |
- 				AR531X_RESET_WARM_WLAN0_MAC |
- 				AR531X_RESET_WARM_WLAN0_BB);
- 			enable = AR531X_ENABLE_WLAN0;
- 			break;
--		case AR531X_WLAN1_NUM:
-+		case 1:
- 			reset = (AR531X_RESET_WLAN1 |
- 				AR531X_RESET_WARM_WLAN1_MAC |
- 				AR531X_RESET_WARM_WLAN1_BB);
-@@ -144,10 +139,10 @@ ahb_disable_wmac(u_int16_t devid, u_int1
- 		*en &= ~AR5315_ARB_WLAN;
- 	} else {
- 		switch (wlanNum) {
--		case AR531X_WLAN0_NUM:
-+		case 0:
- 			enable = AR531X_ENABLE_WLAN0;
- 			break;
--		case AR531X_WLAN1_NUM:
-+		case 1:
- 			enable = AR531X_ENABLE_WLAN1;
- 			break;
- 		default:
-@@ -159,29 +154,6 @@ ahb_disable_wmac(u_int16_t devid, u_int1
- }
- 
- 
--static int
--exit_ath_wmac(u_int16_t wlanNum, struct ar531x_config *config)
--{
--	struct ath_ahb_softc *sc = sclist[wlanNum];
--	struct net_device *dev;
--	u_int16_t devid;
--
--	if (sc == NULL)
--		return -ENODEV; /* XXX: correct return value? */
--
--	dev = sc->aps_sc.sc_dev;
--	ath_detach(dev);
--	if (dev->irq)
--		free_irq(dev->irq, dev);
--	devid = sc->aps_sc.devid;
--	config->tag = (void *)((unsigned long) devid);
--
--	ahb_disable_wmac(devid, wlanNum);
--	free_netdev(dev);
--	sclist[wlanNum] = NULL;
--	return 0;
--}
--
- static const char ubnt[] = "Ubiquiti Networks";
- /* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
- static const struct ath_hw_detect cards[] = {
-@@ -201,6 +173,114 @@ static const struct ath_hw_detect cards[
- 	{ ubnt, "Bullet5",             PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc205 },
- };
- 
-+static void
-+ahb_hw_detect(struct ath_ahb_softc *sc, const char *radio)
-+{
-+	u16 *radio_data = (u16 *) radio;
-+	if (radio_data) {
-+		u16 vendor, id, subvendor, subid;
-+		vendor = radio_data[1];
-+		id = radio_data[0];
-+		subvendor = radio_data[8];
-+		subid = radio_data[7];
-+		ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
-+	}
-+}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
-+
-+static int ahb_wmac_probe(struct platform_device *pdev)
-+{
-+	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
-+	struct ath_ahb_softc *sc;
-+	struct net_device *dev;
-+	struct resource *res;
-+	const char *athname;
-+	int err;
-+
-+	ahb_enable_wmac(bcfg->devid, pdev->id);
-+	dev = alloc_netdev(sizeof(struct ath_ahb_softc), "wifi%d", ether_setup);
-+	if (!dev)
-+		return -ENOMEM;
-+
-+	sc = dev->priv;
-+	sc->aps_sc.sc_dev = dev;
-+
-+	dev->irq = platform_get_irq(pdev, 0);
-+	if (dev->irq <= 0) {
-+		printk("%s: Cannot find IRQ resource\n", dev->name);
-+		goto error;
-+	}
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	if (!res) {
-+		printk("%s: Cannot find MMIO resource\n", dev->name);
-+		goto error;
-+	}
-+
-+	dev->mem_start = KSEG1ADDR(res->start);
-+	dev->mem_end = KSEG1ADDR(res->end);
-+	sc->aps_sc.sc_iobase = (void __iomem *) dev->mem_start;
-+	sc->aps_sc.sc_bdev = NULL;
-+
-+	/* bus information for the HAL */
-+	sc->aps_config.board = (const struct ar531x_boarddata *) bcfg->config;
-+	sc->aps_config.radio = bcfg->radio;
-+	sc->aps_config.unit = pdev->id;
-+	sc->aps_config.tag = NULL;
-+
-+	err = ath_attach(bcfg->devid, dev, &sc->aps_config);
-+	if (err != 0) {
-+		printk("%s: ath_attach failed: %d\n", dev->name, err);
-+		goto error;
-+	}
-+
-+	athname = ath_hal_probe(ATHEROS_VENDOR_ID, bcfg->devid);
-+	printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
-+		dev_info, dev->name, athname ? athname : "Atheros ???", dev->mem_start, dev->irq);
-+
-+	if (request_irq(dev->irq, ath_intr, IRQF_SHARED|IRQF_DISABLED, dev->name, dev)) {
-+		printk(KERN_WARNING "%s: %s: request_irq failed\n", dev_info, dev->name);
-+		goto error;
-+	}
-+
-+	sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
-+	sc->aps_sc.sc_ledpin = bcfg->config->sysLedGpio;
-+	sc->aps_sc.sc_invalid = 0;
-+	ahb_hw_detect(sc, bcfg->radio);
-+	platform_set_drvdata(pdev, dev);
-+	return 0;
-+
-+error_dev:
-+	free_irq(dev->irq, dev);
-+error:
-+	free_netdev(dev);
-+
-+	return -ENODEV;
-+}
-+
-+
-+static int ahb_wmac_remove(struct platform_device *pdev)
-+{
-+	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
-+	struct net_device *dev;
-+
-+	dev = platform_get_drvdata(pdev);
-+	ath_detach(dev);
-+
-+	if (dev->irq)
-+		free_irq(dev->irq, dev);
-+
-+	ahb_disable_wmac(bcfg->devid, pdev->id);
-+	free_netdev(dev);
-+
-+	return 0;
-+}
-+
-+#else
-+
-+static struct ath_ahb_softc *sclist[2] = {NULL, NULL};
-+
- static int
- init_ath_wmac(u_int16_t devid, u_int16_t wlanNum, struct ar531x_config *config)
- {
-@@ -253,7 +333,7 @@ init_ath_wmac(u_int16_t devid, u_int16_t
- 	sc->aps_sc.sc_iobase = (void __iomem *) dev->mem_start;
- 	sc->aps_sc.sc_bdev = NULL;
- 
--	if (request_irq(dev->irq, ath_intr, IRQF_SHARED, dev->name, dev)) {
-+	if (request_irq(dev->irq, ath_intr, IRQF_SHARED|IRQF_DISABLED, dev->name, dev)) {
- 		printk(KERN_WARNING "%s: %s: request_irq failed\n", dev_info, dev->name);
- 		goto bad3;
- 	}
-@@ -263,21 +343,12 @@ init_ath_wmac(u_int16_t devid, u_int16_t
- 	athname = ath_hal_probe(ATHEROS_VENDOR_ID, devid);
- 	printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
- 		dev_info, dev->name, athname ? athname : "Atheros ???", dev->mem_start, dev->irq);
--	num_activesc++;
- 	/* Ready to process interrupts */
- 
- 	sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
- 	sc->aps_sc.sc_ledpin = config->board->sysLedGpio;
- 	sc->aps_sc.sc_invalid = 0;
--	radio_data = (u16 *) config->radio;
--	if (radio_data) {
--		u16 vendor, id, subvendor, subid;
--		vendor = radio_data[1];
--		id = radio_data[0];
--		subvendor = radio_data[8];
--		subid = radio_data[7];
--		ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
--	}
-+	ahb_hw_detect(sc, config->radio);
- 
- 	return 0;
- 
-@@ -292,6 +363,29 @@ init_ath_wmac(u_int16_t devid, u_int16_t
- 	return -ENODEV;
- }
- 
-+static int
-+exit_ath_wmac(u_int16_t wlanNum, struct ar531x_config *config)
-+{
-+	struct ath_ahb_softc *sc = sclist[wlanNum];
-+	struct net_device *dev;
-+	u_int16_t devid;
-+
-+	if (sc == NULL)
-+		return -ENODEV; /* XXX: correct return value? */
-+
-+	dev = sc->aps_sc.sc_dev;
-+	ath_detach(dev);
-+	if (dev->irq)
-+		free_irq(dev->irq, dev);
-+	devid = sc->aps_sc.devid;
-+	config->tag = (void *)((unsigned long) devid);
-+
-+	ahb_disable_wmac(devid, wlanNum);
-+	free_netdev(dev);
-+	sclist[wlanNum] = NULL;
-+	return 0;
-+}
-+
- static int ahb_wmac_probe(struct platform_device *pdev)
- {
- 	u_int16_t devid;
-@@ -312,11 +406,18 @@ static int ahb_wmac_remove(struct platfo
- 	return 0;
- }
- 
-+#endif
-+
- static struct platform_driver ahb_wmac_driver = {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
-+	.driver.name = "ar231x-wmac",
-+#else
- 	.driver.name = "ar531x-wmac",
-+#endif
- 	.probe = ahb_wmac_probe,
- 	.remove = ahb_wmac_remove
- };
-+
- int
- ath_ioctl_ethtool(struct ath_softc *sc, int cmd, void __user *addr)
- {
diff --git a/package/madwifi/patches/411-autochannel_multi.patch b/package/madwifi/patches/411-autochannel_multi.patch
deleted file mode 100644
index d05c447f7b..0000000000
--- a/package/madwifi/patches/411-autochannel_multi.patch
+++ /dev/null
@@ -1,347 +0,0 @@
---- a/net80211/ieee80211_scan.c
-+++ b/net80211/ieee80211_scan.c
-@@ -97,6 +97,123 @@ struct scan_state {
- static void scan_restart_pwrsav(unsigned long);
- static void scan_next(unsigned long);
- 
-+spinlock_t channel_lock = SPIN_LOCK_UNLOCKED;
-+static LIST_HEAD(channels_inuse);
-+
-+struct channel_inuse {
-+	struct list_head list;
-+	struct ieee80211com *ic;
-+	u16 freq;
-+	u8 bw;
-+};
-+
-+static inline u32
-+get_signal(u8 bw, u8 distance)
-+{
-+	u32 v;
-+
-+	/* signal = 1 - (distance / bw)^2 [scale: 100] */
-+	v = 100 * distance / bw;
-+	v = (100 - ((v * v) / 100));
-+	return v;
-+}
-+
-+static u32
-+get_overlap(u16 f1, u16 f2, u8 b1, u8 b2)
-+{
-+	u32 v;
-+	u16 d, c;
-+
-+	/* add offsets for sidechannel interference */
-+	b1 += (b1 / 5);
-+	b2 += (b2 / 5);
-+
-+	/* use only one direction */
-+	b1 /= 2;
-+	b2 /= 2;
-+
-+	if (f1 + b1 < f2 - b2)
-+		return 0;
-+
-+	d = f2 - f1;
-+	c = d * b1 / (b1 + b2);
-+	v = get_signal(b1, c);
-+
-+	return v * v / 100;
-+}
-+
-+static u8
-+get_channel_bw(struct ieee80211_channel *c)
-+{
-+	switch(c->ic_flags & (
-+		IEEE80211_CHAN_HALF |
-+		IEEE80211_CHAN_QUARTER |
-+		IEEE80211_CHAN_TURBO |
-+		IEEE80211_CHAN_STURBO)) {
-+	case IEEE80211_CHAN_QUARTER:
-+		return 5;
-+	case IEEE80211_CHAN_HALF:
-+		return 10;
-+	case IEEE80211_CHAN_TURBO:
-+	case IEEE80211_CHAN_STURBO:
-+		return 40;
-+	default:
-+		return 20;
-+	}
-+}
-+
-+/* must be called with channel_lock held */
-+u32
-+ieee80211_scan_get_bias(struct ieee80211_channel *c)
-+{
-+	struct channel_inuse *ch;
-+	u8 bw = get_channel_bw(c);
-+	u32 bias = 0;
-+
-+	list_for_each_entry(ch, &channels_inuse, list) {
-+		if (ch->freq == c->ic_freq) {
-+			bias += 50;
-+			continue;
-+		}
-+		if (c->ic_freq < ch->freq)
-+			bias += get_overlap(c->ic_freq, ch->freq, bw, ch->bw);
-+		else
-+			bias += get_overlap(ch->freq, c->ic_freq, ch->bw, bw);
-+	}
-+	return bias;
-+}
-+EXPORT_SYMBOL(ieee80211_scan_get_bias);
-+
-+/* must be called with channel_lock held */
-+void
-+ieee80211_scan_set_bss_channel(struct ieee80211com *ic, struct ieee80211_channel *c)
-+{
-+	unsigned long flags;
-+	struct channel_inuse *ch;
-+
-+	list_for_each_entry(ch, &channels_inuse, list) {
-+		if (ch->ic == ic)
-+			goto found;
-+	}
-+	ch = NULL;
-+found:
-+	if (c && (c != IEEE80211_CHAN_ANYC)) {
-+		if (!ch) {
-+			ch = kmalloc(sizeof(struct channel_inuse), GFP_ATOMIC);
-+			ch->ic = ic;
-+			INIT_LIST_HEAD(&ch->list);
-+			list_add(&ch->list, &channels_inuse);
-+		}
-+		ch->freq = c->ic_freq;
-+		ch->bw = get_channel_bw(c);
-+	} else if (ch) {
-+		list_del(&ch->list);
-+		kfree(ch);
-+	}
-+}
-+EXPORT_SYMBOL(ieee80211_scan_set_bss_channel);
-+
-+
- void
- ieee80211_scan_attach(struct ieee80211com *ic)
- {
-@@ -1169,7 +1286,7 @@ ieee80211_scan_dfs_action(struct ieee802
- 				IEEE80211_RADAR_CHANCHANGE_TBTT_COUNT;
- 			ic->ic_flags |= IEEE80211_F_CHANSWITCH;
- 		} else {
--
-+			unsigned long flags;
- 			IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
- 					"%s: directly switching to channel "
- 					"%3d (%4d MHz)\n", __func__,
-@@ -1180,6 +1297,9 @@ ieee80211_scan_dfs_action(struct ieee802
- 			 * change the channel here. */
- 			change_channel(ic, new_channel);
- 			ic->ic_bsschan = new_channel;
-+			spin_lock_irqsave(&channel_lock, flags);
-+			ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
-+			spin_unlock_irqrestore(&channel_lock, flags);
- 			if (vap->iv_bss)
- 				vap->iv_bss->ni_chan = new_channel;
- 		}
---- a/net80211/ieee80211_scan.h
-+++ b/net80211/ieee80211_scan.h
-@@ -35,6 +35,7 @@
- 
- #define	IEEE80211_SCAN_MAX	IEEE80211_CHAN_MAX
- 
-+extern spinlock_t channel_lock;
- struct ieee80211_scanner;
- struct ieee80211_scan_entry;
- 
-@@ -116,6 +117,8 @@ void ieee80211_scan_flush(struct ieee802
- struct ieee80211_scan_entry;
- typedef int ieee80211_scan_iter_func(void *, const struct ieee80211_scan_entry *);
- int ieee80211_scan_iterate(struct ieee80211com *, ieee80211_scan_iter_func *, void *);
-+u32 ieee80211_scan_get_bias(struct ieee80211_channel *c);
-+void ieee80211_scan_set_bss_channel(struct ieee80211com *ic, struct ieee80211_channel *c);
- 
- /*
-  * Parameters supplied when adding/updating an entry in a
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -373,8 +373,16 @@ void
- ieee80211_ifdetach(struct ieee80211com *ic)
- {
- 	struct ieee80211vap *vap;
-+	unsigned long flags;
- 	int count;
- 
-+	/* mark the channel as no longer in use */
-+	ic->ic_bsschan = IEEE80211_CHAN_ANYC;
-+	spin_lock_irqsave(&channel_lock, flags);
-+	ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
-+	spin_unlock_irqrestore(&channel_lock, flags);
-+
-+
- 	/* bring down all vaps */
- 	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- 		ieee80211_stop(vap->iv_dev);
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -2775,6 +2775,7 @@ static void
- ieee80211_doth_switch_channel(struct ieee80211vap *vap)
- {
- 	struct ieee80211com *ic = vap->iv_ic;
-+	unsigned long flags;
- 
- 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
- 			  "%s: Channel switch to %3d (%4d MHz) NOW!\n",
-@@ -2797,6 +2798,9 @@ ieee80211_doth_switch_channel(struct iee
- 
- 	ic->ic_curchan = ic->ic_bsschan = vap->iv_csa_chan;
- 	ic->ic_set_channel(ic);
-+	spin_lock_irqsave(&channel_lock, flags);
-+	ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
-+	spin_unlock_irqrestore(&channel_lock, flags);
- }
- 
- static void
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -308,6 +308,7 @@ ieee80211_create_ibss(struct ieee80211va
- {
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_node *ni;
-+	unsigned long flags;
- 
- 	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
- 		"%s: creating ibss on channel %u\n", __func__,
-@@ -386,6 +387,9 @@ ieee80211_create_ibss(struct ieee80211va
- 	ic->ic_bsschan = chan;
- 	ieee80211_node_set_chan(ic, ni);
- 	ic->ic_curmode = ieee80211_chan2mode(chan);
-+	spin_lock_irqsave(&channel_lock, flags);
-+	ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
-+	spin_unlock_irqrestore(&channel_lock, flags);
- 
- 	/* Update country ie information */
- 	ieee80211_build_countryie(ic);
-@@ -622,6 +626,7 @@ ieee80211_sta_join1(struct ieee80211_nod
- 	struct ieee80211vap *vap = selbs->ni_vap;
- 	struct ieee80211com *ic = selbs->ni_ic;
- 	struct ieee80211_node *obss;
-+	unsigned long flags;
- 	int canreassoc;
- 
- 	if (vap->iv_opmode == IEEE80211_M_IBSS) {
-@@ -650,6 +655,9 @@ ieee80211_sta_join1(struct ieee80211_nod
- 	ic->ic_curchan = ic->ic_bsschan;
- 	ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan);
- 	ic->ic_set_channel(ic);
-+	spin_lock_irqsave(&channel_lock, flags);
-+	ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
-+	spin_unlock_irqrestore(&channel_lock, flags);
- 	/*
- 	 * Set the erp state (mostly the slot time) to deal with
- 	 * the auto-select case; this should be redundant if the
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -1231,6 +1231,7 @@ ieee80211_dturbo_switch(struct ieee80211
- 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- #endif
- 	struct ieee80211_channel *chan;
-+	unsigned long flags;
- 
- 	chan = ieee80211_find_channel(ic, ic->ic_bsschan->ic_freq, newflags);
- 	if (chan == NULL) {		/* XXX should not happen */
-@@ -1249,6 +1250,9 @@ ieee80211_dturbo_switch(struct ieee80211
- 	ic->ic_bsschan = chan;
- 	ic->ic_curchan = chan;
- 	ic->ic_set_channel(ic);
-+	spin_lock_irqsave(&channel_lock, flags);
-+	ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
-+	spin_unlock_irqrestore(&channel_lock, flags);
- 	/* NB: do not need to reset ERP state because in sta mode */
- }
- EXPORT_SYMBOL(ieee80211_dturbo_switch);
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -4076,8 +4076,13 @@ ieee80211_ioctl_setchanlist(struct net_d
- 	if (nchan == 0)			/* no valid channels, disallow */
- 		return -EINVAL;
- 	if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&	/* XXX */
--	    isclr(chanlist, ic->ic_bsschan->ic_ieee))
-+	    isclr(chanlist, ic->ic_bsschan->ic_ieee)) {
-+		unsigned long flags;
- 		ic->ic_bsschan = IEEE80211_CHAN_ANYC;	/* invalidate */
-+		spin_lock_irqsave(&channel_lock, flags);
-+		ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
-+		spin_unlock_irqrestore(&channel_lock, flags);
-+	}
- 
- 	memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active));
- 	/* update Supported Channels information element */
---- a/net80211/ieee80211_scan_ap.c
-+++ b/net80211/ieee80211_scan_ap.c
-@@ -208,9 +208,15 @@ ap_start(struct ieee80211_scan_state *ss
- 	struct ieee80211com *ic     = NULL;
- 	int i;
- 	unsigned int mode = 0;
-+	unsigned long sflags;
- 
- 	SCAN_AP_LOCK_IRQ(as);
- 	ic = vap->iv_ic;
-+
-+	spin_lock_irqsave(&channel_lock, sflags);
-+	ieee80211_scan_set_bss_channel(ic, NULL);
-+	spin_unlock_irqrestore(&channel_lock, sflags);
-+
- 	/* Determine mode flags to match, or leave zero for auto mode */
- 	ss->ss_last = 0;
- 	ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode);
-@@ -423,8 +429,10 @@ pc_cmp_idletime(struct ieee80211_channel
- 	if (!a->ic_idletime || !b->ic_idletime)
- 		return 0;
- 
--	/* a is better than b (return < 0) when a has more idle time than b */
--	return b->ic_idletime - a->ic_idletime;
-+	/* a is better than b (return < 0) when a has more idle and less bias time than b */
-+	return
-+		((100 - (u32) a->ic_idletime) + ieee80211_scan_get_bias(a)) -
-+		((100 - (u32) b->ic_idletime) + ieee80211_scan_get_bias(b));
- }
- 
- 
-@@ -575,6 +583,7 @@ ap_end(struct ieee80211_scan_state *ss,
- 	struct ap_state *as = ss->ss_priv;
- 	struct ieee80211_channel *bestchan = NULL;
- 	struct ieee80211com *ic = NULL;
-+	unsigned long sflags;
- 	int res = 1;
- 
- 	SCAN_AP_LOCK_IRQ(as);
-@@ -586,8 +595,11 @@ ap_end(struct ieee80211_scan_state *ss,
- 
- 	/* record stats for the channel that was scanned last */
- 	ic->ic_set_channel(ic);
-+	spin_lock_irqsave(&channel_lock, sflags);
-+	ieee80211_scan_set_bss_channel(ic, NULL);
- 	bestchan = pick_channel(ss, vap, flags);
- 	if (bestchan == NULL) {
-+		spin_unlock_irqrestore(&channel_lock, sflags);
- 		if (ss->ss_last > 0) {
- 			/* no suitable channel, should not happen */
- 			printk(KERN_ERR "%s: %s: no suitable channel! "
-@@ -606,6 +618,7 @@ ap_end(struct ieee80211_scan_state *ss,
- 					bestchan->ic_freq, bestchan->ic_flags &
- 					~IEEE80211_CHAN_TURBO)) == NULL) {
- 				/* should never happen ?? */
-+				spin_unlock_irqrestore(&channel_lock, sflags);
- 				SCAN_AP_UNLOCK_IRQ_EARLY(as);
- 				return 0;
- 			}
-@@ -618,6 +631,9 @@ ap_end(struct ieee80211_scan_state *ss,
- 			as->as_action = action;
- 		as->as_selbss = se;
- 
-+		ieee80211_scan_set_bss_channel(ic, bestchan);
-+		spin_unlock_irqrestore(&channel_lock, sflags);
-+
- 		/* Must defer action to avoid possible recursive call through 
- 		 * 80211 state machine, which would result in recursive 
- 		 * locking. */
diff --git a/package/madwifi/patches/412-fragmentation_fix.patch b/package/madwifi/patches/412-fragmentation_fix.patch
deleted file mode 100644
index 92c411b2bf..0000000000
--- a/package/madwifi/patches/412-fragmentation_fix.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -3684,6 +3684,7 @@ ff_bypass:
- 		 *  already alloc'd
- 		 */
- 		ATH_TXBUF_LOCK_IRQ(sc);
-+		STAILQ_INSERT_TAIL(&bf_head, bf, bf_list);
- 		for (bfcnt = 1; bfcnt < framecnt; ++bfcnt) {
- 			tbf = ath_take_txbuf_locked(sc);
- 			if (tbf == NULL)
diff --git a/package/madwifi/patches/413-rxorn.patch b/package/madwifi/patches/413-rxorn.patch
deleted file mode 100644
index 0e8d885da6..0000000000
--- a/package/madwifi/patches/413-rxorn.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -2308,6 +2308,17 @@ ath_intr(int irq, void *dev_id, struct p
- 
- 	sc->sc_isr = status;
- 	status &= sc->sc_imask;			/* discard unasked for bits */
-+
-+	/* Treat RXORN as non-fatal. Either the bus is busy or the CPU
-+	 * is not fast enough to process all frames. Treat it like
-+	 * an Rx interrupt
-+	 */
-+	if (status & HAL_INT_RXORN) {
-+		sc->sc_stats.ast_rxorn++;
-+		status &= ~HAL_INT_RXORN;
-+		status |= HAL_INT_RX;
-+	}
-+
- 	/* As soon as we know we have a real interrupt we intend to service, 
- 	 * we will check to see if we need an initial hardware TSF reading. 
- 	 * Normally we would just populate this all the time to keep things
-@@ -2320,10 +2331,6 @@ ath_intr(int irq, void *dev_id, struct p
- 		sc->sc_stats.ast_hardware++;
- 		ath_hal_intrset(ah, 0);		/* disable intr's until reset */
- 		ATH_SCHEDULE_TQUEUE(&sc->sc_fataltq, &needmark);
--	} else if (status & HAL_INT_RXORN) {
--		sc->sc_stats.ast_rxorn++;
--		ath_hal_intrset(ah, 0);		/* disable intr's until reset */
--		ATH_SCHEDULE_TQUEUE(&sc->sc_rxorntq, &needmark);
- 	} else {
- 		if (status & HAL_INT_SWBA) {
- 			struct ieee80211vap * vap;
diff --git a/package/madwifi/patches/414-txpower.patch b/package/madwifi/patches/414-txpower.patch
deleted file mode 100644
index 3c18bd6fe0..0000000000
--- a/package/madwifi/patches/414-txpower.patch
+++ /dev/null
@@ -1,262 +0,0 @@
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -270,6 +270,7 @@ ieee80211_ifattach(struct ieee80211com *
- 		("invalid number of channels specified: %u", ic->ic_nchans));
- 	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
- 	ic->ic_modecaps |= 1 << IEEE80211_MODE_AUTO;
-+	ic->ic_max_txpower = IEEE80211_TXPOWER_MIN;
- 
- 	for (i = 0; i < ic->ic_nchans; i++) {
- 		c = &ic->ic_channels[i];
-@@ -277,6 +278,7 @@ ieee80211_ifattach(struct ieee80211com *
- 		KASSERT(c->ic_ieee < IEEE80211_CHAN_MAX,
- 			("channel with bogus ieee number %u", c->ic_ieee));
- 		setbit(ic->ic_chan_avail, c->ic_ieee);
-+		ic->ic_max_txpower = max(ic->ic_max_txpower, (u16) (c->ic_maxpower * 2));
- 
- 		if (c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT)
- 			c->ic_scanflags |= IEEE80211_NOSCAN_SET;
-@@ -346,8 +348,6 @@ ieee80211_ifattach(struct ieee80211com *
- 	TAILQ_INIT(&ic->ic_vaps);
- 
- 	ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
--	ic->ic_txpowlimit = IEEE80211_TXPOWER_MIN;
--	ic->ic_newtxpowlimit = IEEE80211_TXPOWER_MAX;
- 
- 	init_timer(&ic->ic_dfs_excl_timer);
- 	ic->ic_dfs_excl_timer.function = 
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -1125,7 +1125,7 @@ ieee80211_alloc_node(struct ieee80211vap
- 
- 		ni->ni_chan = IEEE80211_CHAN_ANYC;
- 		ni->ni_authmode = IEEE80211_AUTH_OPEN;
--		ni->ni_txpower = ic->ic_txpowlimit;
-+		ni->ni_txpower = IEEE80211_TXPOWER_MAX;
- 
- 		ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey,
- 			IEEE80211_KEYIX_NONE);
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -343,8 +343,8 @@ struct ieee80211com {
- 	u_int16_t ic_holdover;			/* PM hold over duration */
- 	u_int16_t ic_bmissthreshold;		/* beacon miss threshold (# beacons) */
- 	unsigned long ic_bmiss_guard;		/* when to cease ignoring bmiss (jiffies) */
--	u_int16_t ic_txpowlimit; 		/* global tx power limit (in 0.5 dBm) */
--	u_int16_t ic_newtxpowlimit; 		/* tx power limit to change to (in 0.5 dBm) */
-+	u_int16_t ic_txpowlimit; 		/* configured global tx power limit (in 0.5 dBm) */
-+	u_int16_t ic_max_txpower;			/* global hardware tx power limit */
- 	u_int16_t ic_uapsdmaxtriggers; 		/* max triggers that could arrive */
- 	u_int8_t ic_coverageclass; 		/* coverage class */
- 	u_int8_t ic_protmode_rssi;			/* rssi threshold for protection mode */
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -908,6 +908,21 @@ ieee80211_ioctl_giwessid(struct net_devi
- 	return 0;
- }
- 
-+static u16
-+ieee80211_get_maxtxpow(struct ieee80211com *ic)
-+{
-+	u_int16_t txp = IEEE80211_TXPOWER_MAX;
-+
-+	if (ic->ic_bsschan && (ic->ic_bsschan != IEEE80211_CHAN_ANYC))
-+		txp = min(txp, (u16) ic->ic_bsschan->ic_maxpower);
-+
-+	if (ic->ic_max_txpower > 0)
-+		txp = min(txp, ic->ic_max_txpower);
-+
-+	return txp;
-+}
-+
-+
- static int
- ieee80211_ioctl_giwrange(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
-@@ -920,17 +935,21 @@ ieee80211_ioctl_giwrange(struct net_devi
- 	u_int8_t reported[IEEE80211_CHAN_BYTES];	/* XXX stack usage? */
- 	int i, r;
- 	int step = 0;
-+	u_int16_t power;
- 
- 	data->length = sizeof(struct iw_range);
- 	memset(range, 0, sizeof(struct iw_range));
- 
-+	power = ieee80211_get_maxtxpow(ic);
-+
- 	/* txpower (128 values, but will print out only IW_MAX_TXPOWER) */
--	range->num_txpower = (ic->ic_txpowlimit >= 8) ? IW_MAX_TXPOWER : ic->ic_txpowlimit;
--	step = ic->ic_txpowlimit / (2 * (IW_MAX_TXPOWER - 1));
-+	power /= 2; /* Unit: 0.5 dBm */
-+	range->num_txpower = (power >= 8) ? IW_MAX_TXPOWER : power;
-+	step = power / (IW_MAX_TXPOWER - 1);
- 
- 	range->txpower[0] = 0;
- 	for (i = 1; i < IW_MAX_TXPOWER; i++)
--		range->txpower[i] = (ic->ic_txpowlimit/2)
-+		range->txpower[i] = power
- 			- (IW_MAX_TXPOWER - i - 1) * step;
- 
- 	range->txpower_capa = IW_TXPOW_DBM;
-@@ -1379,13 +1398,11 @@ ieee80211_ioctl_siwtxpow(struct net_devi
- 	int fixed, disabled;
- 
- 	fixed = (ic->ic_flags & IEEE80211_F_TXPOW_FIXED);
--	disabled = (fixed && vap->iv_bss->ni_txpower == 0);
-+	disabled = (fixed && ic->ic_txpowlimit == 0);
- 	if (rrq->disabled) {
- 		if (!disabled) {
--			if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0)
--				return -EOPNOTSUPP;
- 			ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;
--			vap->iv_bss->ni_txpower = 0;
-+			ic->ic_txpowlimit = 0;
- 			goto done;
- 		}
- 		return 0;
-@@ -1396,30 +1413,12 @@ ieee80211_ioctl_siwtxpow(struct net_devi
- 			return -EOPNOTSUPP;
- 		if (rrq->flags != IW_TXPOW_DBM)
- 			return -EINVAL;
--		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC) {
--			if ((ic->ic_bsschan->ic_maxregpower >= rrq->value) &&
--			    (ic->ic_txpowlimit/2 >= rrq->value)) {
--				vap->iv_bss->ni_txpower = 2 * rrq->value;
--				ic->ic_newtxpowlimit = 2 * rrq->value;
--				ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;
--			} else
--				return -EINVAL;
--		} else {
--			/*
--			 * No channel set yet
--			 */
--			if (ic->ic_txpowlimit/2 >= rrq->value) {
--				vap->iv_bss->ni_txpower = 2 * rrq->value;
--				ic->ic_newtxpowlimit = 2 * rrq->value;
--				ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;
--			}
--			else
--				return -EINVAL;
--		}
-+		ic->ic_txpowlimit = 2 * rrq->value;
-+		ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;
- 	} else {
- 		if (!fixed)		/* no change */
- 			return 0;
--		ic->ic_newtxpowlimit = IEEE80211_TXPOWER_MAX;
-+		ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
- 		ic->ic_flags &= ~IEEE80211_F_TXPOW_FIXED;
- 	}
- done:
-@@ -1588,9 +1587,18 @@ ieee80211_ioctl_giwtxpow(struct net_devi
- {
- 	struct ieee80211vap *vap = dev->priv;
- 	struct ieee80211com *ic = vap->iv_ic;
--
--	rrq->value = vap->iv_bss->ni_txpower / 2;
--	rrq->fixed = (ic->ic_flags & IEEE80211_F_TXPOW_FIXED) != 0;
-+	unsigned int power = ic->ic_txpowlimit;
-+	struct ieee80211_channel *c;
-+	u_int16_t txp;
-+
-+	txp = ieee80211_get_maxtxpow(ic);
-+	if (ic->ic_flags & IEEE80211_F_TXPOW_FIXED) {
-+		txp = min(txp, ic->ic_txpowlimit);
-+		rrq->fixed = 1;
-+	} else {
-+		rrq->fixed = 0;
-+	}
-+	rrq->value = txp / 2;
- 	rrq->disabled = (rrq->fixed && rrq->value == 0);
- 	rrq->flags = IW_TXPOW_DBM;
- 	return 0;
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -380,7 +380,6 @@ static unsigned int ath_dump_hal_map(str
- static u_int32_t ath_get_clamped_maxtxpower(struct ath_softc *sc);
- static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc, 
- 		u_int32_t new_clamped_maxtxpower);
--static u_int32_t ath_get_real_maxtxpower(struct ath_softc *sc);
- 
- static void ath_poll_disable(struct net_device *dev);
- static void ath_poll_enable(struct net_device *dev);
-@@ -3168,7 +3167,7 @@ ath_tx_startraw(struct net_device *dev,
- 	try0 = ph->try0;
- 	rt = sc->sc_currates;
- 	txrate = dot11_to_ratecode(sc, rt, ph->rate0);
--	power = ph->power > 60 ? 60 : ph->power;
-+	power = ph->power > 63 ? 63 : ph->power;
- 	hdrlen = ieee80211_anyhdrsize(wh);
- 	pktlen = skb->len + IEEE80211_CRC_LEN;
- 
-@@ -8394,7 +8393,7 @@ ath_tx_start(struct net_device *dev, str
- 			    pktlen,			/* packet length */
- 			    hdrlen,			/* header length */
- 			    atype,			/* Atheros packet type */
--			    MIN(ni->ni_txpower, 60),	/* txpower */
-+			    MIN(ni->ni_txpower, 63),	/* txpower */
- 			    txrate, try0,		/* series 0 rate/tries */
- 			    keyix,			/* key cache index */
- 			    antenna,			/* antenna mode */
-@@ -10387,59 +10386,16 @@ ath_get_clamped_maxtxpower(struct ath_so
- 
- /* XXX: this function needs some locking to avoid being called 
-  * twice/interrupted */
--/* 1. Save the currently specified maximum txpower (as clamped by madwifi)
-- * 2. Determine the real maximum txpower the card can support by
-- *    setting a value that exceeds the maximum range (by one) and
-- *    finding out what it limits us to.
-- * 3. Restore the saved maxtxpower value we had previously specified */
--static u_int32_t
--ath_get_real_maxtxpower(struct ath_softc *sc)
--{
--	u_int32_t saved_clamped_maxtxpower;
--	u_int32_t real_maxtxpower;
--
--	saved_clamped_maxtxpower = ath_get_clamped_maxtxpower(sc);
--	real_maxtxpower = 
--		ath_set_clamped_maxtxpower(sc, IEEE80211_TXPOWER_MAX + 1);
--	ath_set_clamped_maxtxpower(sc, saved_clamped_maxtxpower);
--	return real_maxtxpower;
--}
--
--
--/* XXX: this function needs some locking to avoid being called 
-- * twice/interrupted */
- static void
- ath_update_txpow(struct ath_softc *sc)
- {
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ieee80211vap *vap = NULL;
- 	struct ath_hal *ah = sc->sc_ah;
--	u_int32_t prev_clamped_maxtxpower = 0;
--	u_int32_t new_clamped_maxtxpower = 0;
- 
- 	/* Determine the previous value of maxtxpower */
--	prev_clamped_maxtxpower = ath_get_clamped_maxtxpower(sc);
--	/* Determine the real maximum txpower the card can support */
--	ic->ic_txpowlimit = ath_get_real_maxtxpower(sc);
--	/* Grab the new maxtxpower setting (which may have changed) */
--	new_clamped_maxtxpower = ic->ic_newtxpowlimit;
--	/* Make sure the change is within limits, clamp it otherwise */
--	if (ic->ic_newtxpowlimit > ic->ic_txpowlimit)
--		new_clamped_maxtxpower = ic->ic_txpowlimit;
--	/* Search for the VAP that needs a txpow change, if any */
--	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
--		if (!tpc || ic->ic_newtxpowlimit != vap->iv_bss->ni_txpower) {
--			vap->iv_bss->ni_txpower = new_clamped_maxtxpower;
--			ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, 
--					set_node_txpower, 
--					&new_clamped_maxtxpower);
--		}
--	}
--
--	/* Store the assigned (clamped) maximum txpower and update the HAL */
--	sc->sc_curtxpow = new_clamped_maxtxpower;
--	if (new_clamped_maxtxpower != prev_clamped_maxtxpower)
--		ath_hal_settxpowlimit(ah, new_clamped_maxtxpower);
-+	ath_set_clamped_maxtxpower(sc, ic->ic_txpowlimit);
-+	ic->ic_max_txpower = ath_get_clamped_maxtxpower(sc);
- }
- 
- #ifdef ATH_SUPERG_XR
diff --git a/package/madwifi/patches/415-chan_switch.patch b/package/madwifi/patches/415-chan_switch.patch
deleted file mode 100644
index 6dc5da8383..0000000000
--- a/package/madwifi/patches/415-chan_switch.patch
+++ /dev/null
@@ -1,187 +0,0 @@
---- a/net80211/ieee80211_beacon.c
-+++ b/net80211/ieee80211_beacon.c
-@@ -224,18 +224,18 @@ ieee80211_beacon_alloc(struct ieee80211_
- 	pktlen = 8					/* time stamp */
- 		 + sizeof(u_int16_t)			/* beacon interval */
- 		 + sizeof(u_int16_t)			/* capability information */
--		 + 2 + ni->ni_esslen			/* ssid */
-+		 + 2 + IEEE80211_NWID_LEN			/* ssid */
- 		 + 2 + IEEE80211_RATE_SIZE		/* supported rates */
- 		 + 7 					/* FH/DS parameters max(7,3) */
--		 + 2 + 4 + vap->iv_tim_len		/* IBSS/TIM parameter set*/
-+		 + sizeof(struct ieee80211_tim_ie) + 128 /* IBSS/TIM parameter set*/
- 		 + ic->ic_country_ie.country_len + 2	/* country code */
- 		 + 3					/* power constraint */
- 		 + 5					/* channel switch announcement */
- 		 + 3					/* ERP */
- 		 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) /* Ext. Supp. Rates */
--		 + (vap->iv_caps & IEEE80211_C_WME ?	/* WME */
-+		 + (ic->ic_caps & IEEE80211_C_WME ?	/* WME */
- 			sizeof(struct ieee80211_wme_param) : 0)
--		 + (vap->iv_caps & IEEE80211_C_WPA ?	/* WPA 1+2 */
-+		 + (ic->ic_caps & IEEE80211_C_WPA ?	/* WPA 1+2 */
- 			2 * sizeof(struct ieee80211_ie_wpa) : 0)
- 		 + sizeof(struct ieee80211_ie_athAdvCap)
- #ifdef ATH_SUPERG_XR
-@@ -290,17 +290,26 @@ ieee80211_beacon_update(struct ieee80211
- 	IEEE80211_LOCK_IRQ(ic);
- 
- 	/* Check if we need to change channel right now */
--	if ((ic->ic_flags & IEEE80211_F_DOTH) &&
--	    (vap->iv_flags & IEEE80211_F_CHANSWITCH)) {
--		struct ieee80211_channel *c = 
-+	if (ic->ic_flags & IEEE80211_F_CHANSWITCH) {
-+		struct ieee80211_channel *c =
- 			ieee80211_doth_findchan(vap, ic->ic_chanchange_chan);
--		
--		if (!vap->iv_chanchange_count && !c) {
--			vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
--			ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;
--		} else if (vap->iv_chanchange_count &&
--			   ((!ic->ic_chanchange_tbtt) ||
--			    (vap->iv_chanchange_count == ic->ic_chanchange_tbtt))) {
-+		struct ieee80211vap *avp;
-+		int do_switch = 1;
-+
-+		TAILQ_FOREACH(avp, &ic->ic_vaps, iv_next) {
-+			if (!(avp->iv_flags & IEEE80211_F_CHANSWITCH))
-+				continue;
-+
-+			do_switch = 0;
-+			break;
-+		}
-+		if (vap->iv_flags & IEEE80211_F_CHANSWITCH) {
-+			if (vap->iv_chanchange_count-- <= 1) {
-+				vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
-+				vap->iv_chanchange_count = 0;
-+			}
-+		}
-+		if (do_switch) {
- 			u_int8_t *frm;
- 
- 			IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
-@@ -316,16 +325,7 @@ ieee80211_beacon_update(struct ieee80211
- 			} else
- 				ic->ic_bsschan = c;
- 
--			skb_pull(skb, sizeof(struct ieee80211_frame));
--			skb_trim(skb, 0);
--			frm = skb->data;
--			skb_put(skb, ieee80211_beacon_init(ni, bo, frm) - frm);
--			skb_push(skb, sizeof(struct ieee80211_frame));
--
--			vap->iv_chanchange_count = 0;
--			vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
- 			ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;
--
- 			/* NB: Only for the first VAP to get here, and when we
- 			 * have a valid channel to which to change. */
- 			if (c && (ic->ic_curchan != c)) {
-@@ -488,22 +488,20 @@ ieee80211_beacon_update(struct ieee80211
- 
- 	if (IEEE80211_IS_MODE_BEACON(vap->iv_opmode)) {
- 
--		if ((ic->ic_flags & IEEE80211_F_DOTH) &&
--		    (ic->ic_flags & IEEE80211_F_CHANSWITCH)) {
-+		if (ic->ic_flags & IEEE80211_F_CHANSWITCH) {
- 			struct ieee80211_ie_csa *csa_ie =
- 				(struct ieee80211_ie_csa *)bo->bo_chanswitch;
- 
--			IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH, 
-+			if (csa_ie->csa_len == 0) {
-+				IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
- 					"%s: Sending 802.11h chanswitch IE: "
- 					"%d/%d\n", __func__, 
- 					ic->ic_chanchange_chan, 
- 					ic->ic_chanchange_tbtt);
--			if (!vap->iv_chanchange_count) {
--				vap->iv_flags |= IEEE80211_F_CHANSWITCH;
- 
- 				/* copy out trailer to open up a slot */
- 				memmove(bo->bo_chanswitch + sizeof(*csa_ie),
--					bo->bo_chanswitch, 
-+					bo->bo_chanswitch,
- 					bo->bo_chanswitch_trailerlen);
- 
- 				/* add ie in opened slot */
-@@ -523,17 +521,15 @@ ieee80211_beacon_update(struct ieee80211
- 				bo->bo_ath_caps += sizeof(*csa_ie);
- 				bo->bo_xr += sizeof(*csa_ie);
- 
--				/* indicate new beacon length so other layers 
-+				/* indicate new beacon length so other layers
- 				 * may manage memory */
- 				skb_put(skb, sizeof(*csa_ie));
- 				len_changed = 1;
--			} else if(csa_ie->csa_count)
--				csa_ie->csa_count--;
--			
--			vap->iv_chanchange_count++;
--			IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
--				"%s: CHANSWITCH IE, change in %d TBTT\n",
--				__func__, csa_ie->csa_count);
-+
-+				IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
-+					"%s: CHANSWITCH IE, change in %d TBTT\n",
-+					__func__, csa_ie->csa_count);
-+			}
- 		}
- #ifdef ATH_SUPERG_XR
- 		if (vap->iv_flags & IEEE80211_F_XRUPDATE) {
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -699,39 +699,11 @@ ieee80211_ioctl_siwfreq(struct net_devic
- 			if (c == NULL)			/* no channel */
- 				return -EINVAL;
- 		}
--		/*
--		 * Fine tune channel selection based on desired mode:
--		 *   if 11b is requested, find the 11b version of any
--		 *      11g channel returned,
--		 *   if static turbo, find the turbo version of any
--		 *	11a channel return,
--		 *   otherwise we should be ok with what we've got.
--		 */
--		switch (vap->iv_des_mode) {
--		case IEEE80211_MODE_11B:
--			if (IEEE80211_IS_CHAN_ANYG(c)) {
--				c2 = findchannel(ic, i, IEEE80211_MODE_11B);
--				/* NB: should not happen, =>'s 11g w/o 11b */
--				if (c2 != NULL)
--					c = c2;
--			}
--			break;
--		case IEEE80211_MODE_TURBO_A:
--			if (IEEE80211_IS_CHAN_A(c)) {
--				c2 = findchannel(ic, i, IEEE80211_MODE_TURBO_A);
--				if (c2 != NULL)
--					c = c2;
--			}
--			break;
--		default:		/* NB: no static turboG */
--			break;
--		}
-+
- 		if (ieee80211_check_mode_consistency(ic, vap->iv_des_mode, c)) {
- 			if (vap->iv_opmode == IEEE80211_M_HOSTAP)
- 				return -EINVAL;
- 		}
--		if ((vap->iv_state == IEEE80211_S_RUN) && (c == vap->iv_des_chan))
--			return 0;			/* no change, return */
- 
- 		/* Don't allow to change to channel with radar found */
- 		if (c->ic_flags & IEEE80211_CHAN_RADAR)
-@@ -4634,7 +4606,13 @@ static void
- pre_announced_chanswitch(struct net_device *dev, u_int32_t channel, u_int32_t tbtt) {
- 	struct ieee80211vap *vap = dev->priv;
- 	struct ieee80211com *ic = vap->iv_ic;
-+	struct ieee80211vap *avp;
-+
- 	/* now flag the beacon update to include the channel switch IE */
-+	TAILQ_FOREACH(avp, &ic->ic_vaps, iv_next) {
-+		avp->iv_flags |= IEEE80211_F_CHANSWITCH;
-+		avp->iv_chanchange_count = tbtt;
-+	}
- 	ic->ic_flags |= IEEE80211_F_CHANSWITCH;
- 	ic->ic_chanchange_chan = channel;
- 	ic->ic_chanchange_tbtt = tbtt;
diff --git a/package/madwifi/patches/416-wprobe.patch b/package/madwifi/patches/416-wprobe.patch
deleted file mode 100644
index 0b378d7e26..0000000000
--- a/package/madwifi/patches/416-wprobe.patch
+++ /dev/null
@@ -1,549 +0,0 @@
---- /dev/null
-+++ b/ath/ath_wprobe.c
-@@ -0,0 +1,433 @@
-+#include <net80211/ieee80211_node.h>
-+#include <linux/wprobe.h>
-+
-+atomic_t cleanup_tasks = ATOMIC_INIT(0);
-+
-+enum wp_node_val {
-+	WP_NODE_RSSI,
-+	WP_NODE_SIGNAL,
-+	WP_NODE_RX_RATE,
-+	WP_NODE_TX_RATE,
-+	WP_NODE_RETRANSMIT_200,
-+	WP_NODE_RETRANSMIT_400,
-+	WP_NODE_RETRANSMIT_800,
-+	WP_NODE_RETRANSMIT_1600,
-+};
-+
-+enum wp_global_val {
-+	WP_GLOBAL_NOISE,
-+	WP_GLOBAL_PHY_BUSY,
-+	WP_GLOBAL_PHY_RX,
-+	WP_GLOBAL_PHY_TX,
-+	WP_GLOBAL_FRAMES,
-+	WP_GLOBAL_PROBEREQ,
-+};
-+
-+static struct wprobe_item ath_wprobe_globals[] = {
-+	[WP_GLOBAL_NOISE] = {
-+		.name = "noise",
-+		.type = WPROBE_VAL_S16,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_GLOBAL_PHY_BUSY] = {
-+		.name = "phy_busy",
-+		.type = WPROBE_VAL_U8,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_GLOBAL_PHY_RX] = {
-+		.name = "phy_rx",
-+		.type = WPROBE_VAL_U8,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_GLOBAL_PHY_TX] = {
-+		.name = "phy_tx",
-+		.type = WPROBE_VAL_U8,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_GLOBAL_FRAMES] = {
-+		.name = "frames",
-+		.type = WPROBE_VAL_U32,
-+	},
-+	[WP_GLOBAL_PROBEREQ] = {
-+		.name = "probereq",
-+		.type = WPROBE_VAL_U32,
-+	},
-+};
-+
-+static struct wprobe_item ath_wprobe_link[] = {
-+	[WP_NODE_RSSI] = {
-+		.name = "rssi",
-+		.type = WPROBE_VAL_U8,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_NODE_SIGNAL] = {
-+		.name = "signal",
-+		.type = WPROBE_VAL_S16,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_NODE_RX_RATE] = {
-+		.name = "rx_rate",
-+		.type = WPROBE_VAL_U16,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_NODE_TX_RATE] = {
-+		.name = "tx_rate",
-+		.type = WPROBE_VAL_U16,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_NODE_RETRANSMIT_200] = {
-+		.name = "retransmit_200",
-+		.type = WPROBE_VAL_U8,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_NODE_RETRANSMIT_400] = {
-+		.name = "retransmit_400",
-+		.type = WPROBE_VAL_U8,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_NODE_RETRANSMIT_800] = {
-+		.name = "retransmit_800",
-+		.type = WPROBE_VAL_U8,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+	[WP_NODE_RETRANSMIT_1600] = {
-+		.name = "retransmit_1600",
-+		.type = WPROBE_VAL_U8,
-+		.flags = WPROBE_F_KEEPSTAT
-+	},
-+};
-+
-+#define AR5K_MIBC       0x0040
-+#define AR5K_MIBC_FREEZE	(1 << 1)
-+#define AR5K_TXFC       0x80ec
-+#define AR5K_RXFC       0x80f0
-+#define AR5K_RXCLEAR    0x80f4
-+#define AR5K_CYCLES     0x80f8
-+
-+#define READ_CLR(_ah, _reg) \
-+	({ u32 __val = OS_REG_READ(_ah, _reg); OS_REG_WRITE(_ah, _reg, 0); __val; })
-+
-+static bool
-+wprobe_disabled(void)
-+{
-+	return (!wprobe_add_iface || IS_ERR(wprobe_add_iface));
-+}
-+
-+static int
-+ath_wprobe_sync(struct wprobe_iface *dev, struct wprobe_link *l, struct wprobe_value *val, bool measure)
-+{
-+	struct ath_vap *avp = container_of(dev, struct ath_vap, av_wpif);
-+	struct ieee80211vap *vap = &avp->av_vap;
-+	struct ieee80211com *ic = vap->iv_ic;
-+	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_hal *ah = sc->sc_ah;
-+	u32 cc, busy, rx, tx;
-+	s16 noise;
-+
-+	if (l)
-+		goto out;
-+
-+	OS_REG_WRITE(ah, AR5K_MIBC, AR5K_MIBC_FREEZE);
-+	cc = READ_CLR(ah, AR5K_CYCLES);
-+	busy = READ_CLR(ah, AR5K_RXCLEAR);
-+	rx = READ_CLR(ah, AR5K_RXFC);
-+	tx = READ_CLR(ah, AR5K_TXFC);
-+	OS_REG_WRITE(ah, AR5K_MIBC, 0);
-+	noise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan));
-+	ic->ic_channoise = noise;
-+
-+	WPROBE_FILL_BEGIN(val, ath_wprobe_globals);
-+	if (cc & 0xf0000000) {
-+		/* scale down if the counters are near max */
-+		cc >>= 8;
-+		busy >>= 8;
-+		rx >>= 8;
-+		tx >>= 8;
-+	}
-+	if (ah->ah_macType < 5212)
-+		goto phy_skip;
-+	if (!cc)
-+		goto phy_skip;
-+	if (busy > cc)
-+		goto phy_skip;
-+	if (rx > cc)
-+		goto phy_skip;
-+	if (tx > cc)
-+		goto phy_skip;
-+	busy = (busy * 100) / cc;
-+	rx = (rx * 100) / cc;
-+	tx = (tx * 100) / cc;
-+	WPROBE_SET(WP_GLOBAL_PHY_BUSY, U8, busy);
-+	WPROBE_SET(WP_GLOBAL_PHY_RX, U8, rx);
-+	WPROBE_SET(WP_GLOBAL_PHY_TX, U8, tx);
-+	WPROBE_SET(WP_GLOBAL_FRAMES, U32, avp->av_rxframes);
-+	WPROBE_SET(WP_GLOBAL_PROBEREQ, U32, avp->av_rxprobereq);
-+
-+phy_skip:
-+	WPROBE_SET(WP_GLOBAL_NOISE, S16, noise);
-+	WPROBE_FILL_END();
-+
-+out:
-+	return 0;
-+}
-+
-+#undef AR5K_TXFC
-+#undef AR5K_RXFC
-+#undef AR5K_RXCLEAR
-+#undef AR5K_CYCLES
-+#undef AR5K_MIBC
-+#undef AR5K_MIBC_FREEZE
-+#undef READ_CLR
-+
-+static const struct wprobe_iface ath_wprobe_dev = {
-+	.link_items = ath_wprobe_link,
-+	.n_link_items = ARRAY_SIZE(ath_wprobe_link),
-+	.global_items = ath_wprobe_globals,
-+	.n_global_items = ARRAY_SIZE(ath_wprobe_globals),
-+	.sync_data = ath_wprobe_sync,
-+};
-+
-+static int
-+ath_lookup_rateval(struct ieee80211_node *ni, int rate)
-+{
-+	struct ieee80211vap *vap = ni->ni_vap;
-+	struct ieee80211com *ic = vap->iv_ic;
-+	struct ath_softc *sc = ic->ic_dev->priv;
-+	const HAL_RATE_TABLE *rt = sc->sc_currates;
-+
-+	if ((!rt) || (rate < 0) || (rate >= ARRAY_SIZE(sc->sc_hwmap)))
-+		return -1;
-+
-+	rate = sc->sc_hwmap[rate].ieeerate;
-+	rate = sc->sc_rixmap[rate & IEEE80211_RATE_VAL];
-+	if ((rate < 0) || (rate >= rt->rateCount))
-+		return -1;
-+
-+	return rt->info[rate].rateKbps;
-+}
-+
-+static void
-+ath_wprobe_report_rx(struct ieee80211vap *vap, struct ath_rx_status *rs, struct sk_buff *skb)
-+{
-+	const struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
-+	struct wprobe_wlan_hdr hdr;
-+	struct ath_vap *avp;
-+	int hdrsize;
-+
-+	if (wprobe_disabled())
-+		return;
-+
-+	avp = ATH_VAP(vap);
-+	avp->av_rxframes++;
-+	if (wh->i_fc[0] == (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ))
-+		avp->av_rxprobereq++;
-+
-+	memset(&hdr, 0, sizeof(hdr));
-+	hdr.len = skb->len;
-+	hdr.snr = rs->rs_rssi;
-+	hdr.type = WPROBE_PKT_RX;
-+	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
-+		hdrsize = sizeof(struct ieee80211_ctlframe_addr2);
-+	else
-+		hdrsize = ieee80211_hdrsize(skb->data);
-+	wprobe_add_frame(&avp->av_wpif, &hdr, skb->data, hdrsize + 0x42);
-+}
-+
-+
-+static void
-+ath_node_sample_rx(struct ieee80211_node *ni, struct ath_rx_status *rs)
-+{
-+	struct ath_node *an = ATH_NODE(ni);
-+	struct ieee80211vap *vap = ni->ni_vap;
-+	struct ieee80211com *ic = vap->iv_ic;
-+	struct wprobe_link *l = &an->an_wplink;
-+	struct wprobe_value *v = l->val;
-+	unsigned long flags;
-+	int rate;
-+
-+	if (wprobe_disabled() || !an->an_wplink_active || !l->val)
-+		return;
-+
-+	rate = ath_lookup_rateval(ni, rs->rs_rate);
-+
-+	spin_lock_irqsave(&l->iface->lock, flags);
-+	WPROBE_FILL_BEGIN(v, ath_wprobe_link);
-+	WPROBE_SET(WP_NODE_RSSI, U8, rs->rs_rssi);
-+	WPROBE_SET(WP_NODE_SIGNAL, S16, ic->ic_channoise + rs->rs_rssi);
-+	if ((rate > 0) && (rate <= 600000))
-+		WPROBE_SET(WP_NODE_RX_RATE, U16, rate);
-+	WPROBE_FILL_END();
-+	wprobe_update_stats(l->iface, l);
-+	spin_unlock_irqrestore(&l->iface->lock, flags);
-+}
-+
-+static void
-+ath_wprobe_report_tx(struct ieee80211vap *vap, struct ath_tx_status *ts, struct sk_buff *skb)
-+{
-+	const struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
-+	struct wprobe_wlan_hdr hdr;
-+	struct ath_vap *avp;
-+	int hdrsize;
-+
-+	if (wprobe_disabled())
-+		return;
-+
-+	avp = ATH_VAP(vap);
-+
-+	memset(&hdr, 0, sizeof(hdr));
-+	hdr.len = skb->len;
-+	hdr.snr = ts->ts_rssi;
-+	hdr.type = WPROBE_PKT_TX;
-+	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
-+		hdrsize = sizeof(struct ieee80211_ctlframe_addr2);
-+	else
-+		hdrsize = ieee80211_hdrsize(skb->data);
-+	wprobe_add_frame(&avp->av_wpif, &hdr, skb->data, hdrsize + 0x42);
-+}
-+
-+
-+
-+static void
-+ath_node_sample_tx(struct ieee80211_node *ni, struct ath_tx_status *ts, struct sk_buff *skb)
-+{
-+	struct ath_node *an = ATH_NODE(ni);
-+	struct ieee80211vap *vap = ni->ni_vap;
-+	struct ieee80211com *ic = vap->iv_ic;
-+	struct wprobe_link *l = &an->an_wplink;
-+	struct wprobe_value *v = l->val;
-+	unsigned long flags;
-+	int rate, rexmit_counter;
-+	int len = skb->len;
-+
-+	if (wprobe_disabled() || !an->an_wplink_active || !l->val)
-+		return;
-+
-+	ath_wprobe_report_tx(vap, ts, skb);
-+	rate = ath_lookup_rateval(ni, ts->ts_rate);
-+
-+	spin_lock_irqsave(&l->iface->lock, flags);
-+	WPROBE_FILL_BEGIN(v, ath_wprobe_link);
-+	WPROBE_SET(WP_NODE_RSSI, U8, ts->ts_rssi);
-+	WPROBE_SET(WP_NODE_SIGNAL, S16, ic->ic_channoise + ts->ts_rssi);
-+
-+	if (len <= 200)
-+		rexmit_counter = WP_NODE_RETRANSMIT_200;
-+	else if (len <= 400)
-+		rexmit_counter = WP_NODE_RETRANSMIT_400;
-+	else if (len <= 800)
-+		rexmit_counter = WP_NODE_RETRANSMIT_800;
-+	else
-+		rexmit_counter = WP_NODE_RETRANSMIT_1600;
-+	WPROBE_SET(rexmit_counter, U8, ts->ts_longretry);
-+
-+	if ((rate > 0) && (rate <= 600000))
-+		WPROBE_SET(WP_NODE_TX_RATE, U16, rate);
-+	WPROBE_FILL_END();
-+	wprobe_update_stats(l->iface, l);
-+	spin_unlock_irqrestore(&l->iface->lock, flags);
-+}
-+
-+static void
-+ath_wprobe_node_join(struct ieee80211vap *vap, struct ieee80211_node *ni)
-+{
-+	struct wprobe_iface *dev;
-+	struct wprobe_link *l;
-+	struct ath_vap *avp;
-+	struct ath_node *an = ATH_NODE(ni);
-+
-+	if (wprobe_disabled() || an->an_wplink_active)
-+		return;
-+
-+	avp = ATH_VAP(vap);
-+	dev = &avp->av_wpif;
-+	l = &an->an_wplink;
-+
-+	ieee80211_ref_node(ni);
-+	wprobe_add_link(dev, l, ni->ni_macaddr);
-+	an->an_wplink_active = 1;
-+}
-+
-+static void
-+ath_wprobe_do_node_leave(struct work_struct *work)
-+{
-+	struct ath_node *an = container_of(work, struct ath_node, an_destroy);
-+	struct ieee80211_node *ni = &an->an_node;
-+	struct ieee80211vap *vap = ni->ni_vap;
-+	struct wprobe_iface *dev;
-+	struct wprobe_link *l;
-+	struct ath_vap *avp;
-+
-+	avp = ATH_VAP(vap);
-+	dev = &avp->av_wpif;
-+	l = &an->an_wplink;
-+
-+	wprobe_remove_link(dev, l);
-+	ieee80211_unref_node(&ni);
-+	atomic_dec(&cleanup_tasks);
-+}
-+
-+static void
-+ath_wprobe_node_leave(struct ieee80211vap *vap, struct ieee80211_node *ni)
-+{
-+	struct ath_node *an = ATH_NODE(ni);
-+
-+	if (wprobe_disabled() || !an->an_wplink_active)
-+		return;
-+
-+	atomic_inc(&cleanup_tasks);
-+	an->an_wplink_active = 0;
-+	IEEE80211_INIT_WORK(&an->an_destroy, ath_wprobe_do_node_leave);
-+	schedule_work(&an->an_destroy);
-+}
-+
-+static void
-+ath_init_wprobe_dev(struct ath_vap *avp)
-+{
-+	struct ieee80211vap *vap = &avp->av_vap;
-+	struct wprobe_iface *dev = &avp->av_wpif;
-+
-+	if (wprobe_disabled() || (vap->iv_opmode == IEEE80211_M_WDS))
-+		return;
-+
-+	memcpy(dev, &ath_wprobe_dev, sizeof(struct wprobe_iface));
-+	dev->addr = vap->iv_myaddr;
-+	dev->name = vap->iv_dev->name;
-+	wprobe_add_iface(dev);
-+}
-+
-+static void
-+ath_remove_wprobe_dev(struct ath_vap *avp)
-+{
-+	struct ieee80211vap *vap = &avp->av_vap;
-+	struct ieee80211com *ic = vap->iv_ic;
-+	struct ieee80211_node *ni;
-+	struct wprobe_iface *dev = &avp->av_wpif;
-+	struct wprobe_link *l;
-+	struct ath_node *an;
-+	unsigned long flags;
-+
-+	if (wprobe_disabled() || (vap->iv_opmode == IEEE80211_M_WDS))
-+		return;
-+
-+restart:
-+	rcu_read_lock();
-+	list_for_each_entry_rcu(l, &dev->links, list) {
-+		an = container_of(l, struct ath_node, an_wplink);
-+
-+		if (!an->an_wplink_active)
-+			continue;
-+
-+		ni = &an->an_node;
-+		ath_wprobe_node_leave(vap, ni);
-+		rcu_read_unlock();
-+		goto restart;
-+	}
-+	rcu_read_unlock();
-+
-+	/* wait for the cleanup tasks to finish */
-+	while (atomic_read(&cleanup_tasks) != 0) {
-+		schedule();
-+	}
-+
-+	wprobe_remove_iface(dev);
-+}
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -400,6 +400,7 @@ static int countrycode = -1;
- static int maxvaps = -1;
- static int outdoor = -1;
- static int xchanmode = -1;
-+#include "ath_wprobe.c"
- static int beacon_cal = 1;
- 
- static const struct ath_hw_detect generic_hw_info = {
-@@ -1525,6 +1526,7 @@ ath_vap_create(struct ieee80211com *ic,
- 		ath_hal_intrset(ah, sc->sc_imask);
- 	}
- 
-+	ath_init_wprobe_dev(avp);
- 	return vap;
- }
- 
-@@ -1606,6 +1608,7 @@ ath_vap_delete(struct ieee80211vap *vap)
- 		decrease = 0;
- 
- 	ieee80211_vap_detach(vap);
-+	ath_remove_wprobe_dev(ATH_VAP(vap));
- 	/* NB: memory is reclaimed through dev->destructor callback */
- 	if (decrease)
- 		sc->sc_nvaps--;
-@@ -5940,6 +5943,7 @@ ath_node_cleanup(struct ieee80211_node *
- 	/* Clean up node-specific rate things - this currently appears to 
- 	 * always be a no-op */
- 	sc->sc_rc->ops->node_cleanup(sc, ATH_NODE(ni));
-+	ath_wprobe_node_leave(ni->ni_vap, ni);
- 
- 	ATH_NODE_UAPSD_LOCK_IRQ(an);
- #ifdef IEEE80211_DEBUG_REFCNT
-@@ -7010,6 +7014,8 @@ drop_micfail:
- 				goto lookup_slowpath;
- 			}
- 			ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
-+			ath_node_sample_rx(ni, rs);
-+			ath_wprobe_report_rx(ni->ni_vap, rs, skb);
- 			type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
- 			ieee80211_unref_node(&ni);
- 		} else {
-@@ -7024,15 +7030,21 @@ lookup_slowpath:
- 			else
- 				vap = ieee80211_find_rxvap(ic, wh->i_addr1);
- 
--			if (vap)
-+			if (vap) {
-+				ath_wprobe_report_rx(vap, rs, skb);
- 				ni = ieee80211_find_rxnode(ic, vap, wh);
--			else
-+			} else {
-+				TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+					ath_wprobe_report_rx(vap, rs, skb);
-+				}
- 				ni = NULL;
-+			}
- 
- 			if (ni != NULL) {
- 				ieee80211_keyix_t keyix;
- 
- 				ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
-+				ath_node_sample_rx(ni, rs);
- 				type = ieee80211_input(vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
- 				/*
- 				 * If the station has a key cache slot assigned
-@@ -8612,6 +8624,7 @@ ath_tx_processq(struct ath_softc *sc, st
- 				sc->sc_stats.ast_tx_rssi = ts->ts_rssi;
- 				ATH_RSSI_LPF(an->an_halstats.ns_avgtxrssi,
- 					ts->ts_rssi);
-+					ath_node_sample_tx(&an->an_node, ts, bf->bf_skb);
- 				if (bf->bf_skb->priority == WME_AC_VO ||
- 				    bf->bf_skb->priority == WME_AC_VI)
- 					ni->ni_ic->ic_wme.wme_hipri_traffic++;
-@@ -10111,6 +10124,7 @@ ath_newassoc(struct ieee80211_node *ni,
- 	struct ath_softc *sc = ic->ic_dev->priv;
- 
- 	sc->sc_rc->ops->newassoc(sc, ATH_NODE(ni), isnew);
-+	ath_wprobe_node_join(ni->ni_vap, ni);
- 
- 	/* are we supporting compression? */
- 	if (!(vap->iv_ath_cap & ni->ni_ath_flags & IEEE80211_NODE_COMP))
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -46,6 +46,7 @@
- #include "ah_desc.h"
- #include "ah_os.h"
- #include "if_athioctl.h"
-+#include <linux/wprobe.h>
- #include "net80211/ieee80211.h"		/* XXX for WME_NUM_AC */
- #include <asm/io.h>
- #include <linux/list.h>
-@@ -352,6 +353,9 @@ typedef STAILQ_HEAD(, ath_buf) ath_bufhe
- /* driver-specific node state */
- struct ath_node {
- 	struct ieee80211_node an_node;		/* base class */
-+	struct wprobe_link an_wplink;
-+	uint8_t an_wplink_active;
-+	struct work_struct an_destroy;
- 	u_int16_t an_decomp_index; 		/* decompression mask index */
- 	u_int32_t an_avgrssi;			/* average rssi over all rx frames */
- 	u_int8_t  an_prevdatarix;		/* rate ix of last data frame */
-@@ -521,6 +525,9 @@ struct ath_vap {
- #else
- 	unsigned int av_beacon_alloc;
- #endif
-+	struct wprobe_iface av_wpif;
-+	u32 av_rxframes;
-+	u32 av_rxprobereq;
- };
- #define	ATH_VAP(_v)	((struct ath_vap *)(_v))
- 
diff --git a/package/madwifi/patches/417-beacon_txpower.patch b/package/madwifi/patches/417-beacon_txpower.patch
deleted file mode 100644
index 8a59c1211d..0000000000
--- a/package/madwifi/patches/417-beacon_txpower.patch
+++ /dev/null
@@ -1,81 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -395,7 +395,7 @@ static int bstuck_thresh = BSTUCK_THRESH
- static char *autocreate = NULL;
- static char *ratectl = DEF_RATE_CTL;
- static int rfkill = 0;
--static int tpc = 0;
-+static int tpc = 1;
- static int countrycode = -1;
- static int maxvaps = -1;
- static int outdoor = -1;
-@@ -4932,6 +4932,7 @@ ath_beacon_setup(struct ath_softc *sc, s
- 	(((_ic)->ic_flags & (IEEE80211_F_SHPREAMBLE | IEEE80211_F_USEBARKER))\
- 		== IEEE80211_F_SHPREAMBLE)
- 	struct ieee80211com *ic = bf->bf_node->ni_ic;
-+	struct ieee80211vap *vap = bf->bf_node->ni_vap;
- 	struct sk_buff *skb = bf->bf_skb;
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ath_desc *ds;
-@@ -4999,7 +5000,7 @@ ath_beacon_setup(struct ath_softc *sc, s
- 		skb->len + IEEE80211_CRC_LEN,	/* frame length */
- 		sizeof(struct ieee80211_frame), /* header length */
- 		HAL_PKT_TYPE_BEACON,		/* Atheros packet type */
--		bf->bf_node->ni_txpower,        /* txpower XXX */
-+		(vap->iv_beacon_txpow ? vap->iv_beacon_txpow : 63),
- 		rate, 1,			/* series 0 rate/tries */
- 		HAL_TXKEYIX_INVALID,		/* no encryption */
- 		antenna,			/* antenna mode */
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -652,6 +652,7 @@ enum {
- 	IEEE80211_PARAM_WDS_SEP			= 82,	/* move wds stations into separate interfaces */
- 	IEEE80211_PARAM_MAXASSOC		= 83,	/* maximum associated stations */
- 	IEEE80211_PARAM_PROBEREQ		= 84,	/* enable handling of probe requests */
-+	IEEE80211_PARAM_BEACON_TXP		= 85,	/* set beacon tx power */
- };
- 
- #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -254,6 +254,7 @@ struct ieee80211vap {
- 	u_int8_t iv_dtim_period;			/* DTIM period */
- 	u_int8_t iv_dtim_count;				/* DTIM count from last bcn */
- 							/* set/unset aid pwrsav state */
-+	u_int8_t iv_beacon_txpow;			/* beacon tx power */
- 	void (*iv_set_tim)(struct ieee80211_node *, int);
- 	u_int8_t iv_uapsdinfo;				/* sta mode QoS Info flags */
- 	struct ieee80211_node *iv_bss;			/* information for this node */
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2871,6 +2871,9 @@ ieee80211_ioctl_setparam(struct net_devi
- 	case IEEE80211_PARAM_PROBEREQ:
- 		vap->iv_no_probereq = !value;
- 		break;
-+	case IEEE80211_PARAM_BEACON_TXP:
-+		vap->iv_beacon_txpow = value;
-+		break;
- #ifdef ATH_REVERSE_ENGINEERING
- 	case IEEE80211_PARAM_DUMPREGS:
- 		ieee80211_dump_registers(dev, info, w, extra);
-@@ -3236,6 +3239,9 @@ ieee80211_ioctl_getparam(struct net_devi
- 	case IEEE80211_PARAM_PROBEREQ:
- 		param[0] = !vap->iv_no_probereq;
- 		break;
-+	case IEEE80211_PARAM_BEACON_TXP:
-+		param[0] = vap->iv_beacon_txpow;
-+		break;
- 	default:
- 		return -EOPNOTSUPP;
- 	}
-@@ -5810,6 +5816,10 @@ static const struct iw_priv_args ieee802
- 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "probereq"},
- 	{ IEEE80211_PARAM_PROBEREQ,
- 	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_probereq"},
-+	{ IEEE80211_PARAM_BEACON_TXP,
-+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beacon_pwr"},
-+	{ IEEE80211_PARAM_BEACON_TXP,
-+	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_beacon_pwr"},
- 
- #ifdef ATH_REVERSE_ENGINEERING
- 	/*
diff --git a/package/madwifi/patches/419-skb_unmap_crash.patch b/package/madwifi/patches/419-skb_unmap_crash.patch
deleted file mode 100644
index 37602e491a..0000000000
--- a/package/madwifi/patches/419-skb_unmap_crash.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -13499,7 +13499,7 @@ cleanup_ath_buf(struct ath_softc *sc, st
- 	if (bf == NULL) 
- 		return bf;
- 
--	if (bf->bf_skbaddr) {
-+	if (bf->bf_skb && bf->bf_skbaddr) {
- 		bus_unmap_single(
- 			sc->sc_bdev,
- 			bf->bf_skbaddr, 
-@@ -13507,8 +13507,6 @@ cleanup_ath_buf(struct ath_softc *sc, st
- 				sc->sc_rxbufsize : bf->bf_skb->len),
- 			direction);
- 		bf->bf_skbaddr = 0;
--		bf->bf_desc->ds_link = 0;
--		bf->bf_desc->ds_data = 0;
- 	}
- 
- #ifdef ATH_SUPERG_FF
diff --git a/package/madwifi/patches/420-diversity_fix.patch b/package/madwifi/patches/420-diversity_fix.patch
deleted file mode 100644
index 90bcd0e160..0000000000
--- a/package/madwifi/patches/420-diversity_fix.patch
+++ /dev/null
@@ -1,86 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -797,7 +797,6 @@ ath_attach(u_int16_t devid, struct net_d
- 		break;
- 	}
- 
--	sc->sc_setdefantenna = ath_setdefantenna;
- 	sc->sc_rc = ieee80211_rate_attach(sc, ratectl);
- 	if (sc->sc_rc == NULL) {
- 		error = EIO;
-@@ -2624,9 +2623,6 @@ ath_init(struct net_device *dev)
- 	ath_radar_update(sc);
- 	ath_rp_flush(sc);
- 
--	/* Set the default RX antenna; it may get lost on reset. */
--	ath_setdefantenna(sc, sc->sc_defant);
--
- 	/*
- 	 * Setup the hardware after reset: the key cache
- 	 * is filled as needed and the receive engine is
-@@ -3019,7 +3015,6 @@ ath_reset(struct net_device *dev)
- 	ath_setintmit(sc);
- 	ath_update_txpow(sc);		/* update tx power state */
- 	ath_radar_update(sc);
--	ath_setdefantenna(sc, sc->sc_defant);
- 	if (ath_startrecv(sc) != 0)	/* restart recv */
- 		EPRINTF(sc, "Unable to start receive logic.\n");
- 	if (sc->sc_softled)
-@@ -5353,27 +5348,6 @@ ath_beacon_send(struct ath_softc *sc, in
- 	} else if ((sc->sc_updateslot == COMMIT) && (sc->sc_slotupdate == slot))
- 		ath_setslottime(sc);		/* commit change to hardware */
- 
--	if ((!sc->sc_stagbeacons || slot == 0) && (!sc->sc_diversity)) {
--		unsigned int otherant;
--		/*
--		 * Check recent per-antenna transmit statistics and flip
--		 * the default rx antenna if noticeably more frames went out
--		 * on the non-default antenna.  Only do this if rx diversity
--		 * is off.
--		 * XXX assumes 2 antennae
--		 */
--		otherant = sc->sc_defant & 1 ? 2 : 1;
--		if (sc->sc_ant_tx[otherant] > sc->sc_ant_tx[sc->sc_defant] + 
--				ATH_ANTENNA_DIFF) {
--			DPRINTF(sc, ATH_DEBUG_BEACON,
--				"Flip default antenna to %u, %u > %u\n",
--				otherant, sc->sc_ant_tx[otherant],
--				sc->sc_ant_tx[sc->sc_defant]);
--			ath_setdefantenna(sc, otherant);
--		}
--		sc->sc_ant_tx[1] = sc->sc_ant_tx[2] = 0;
--	}
--
- 	if (bfaddr != 0) {
- 		/*
- 		 * Stop any current DMA and put the new frame(s) on the queue.
-@@ -6734,9 +6708,8 @@ ath_setdefantenna(struct ath_softc *sc,
- {
- 	struct ath_hal *ah = sc->sc_ah;
- 
--	/* XXX block beacon interrupts */
--	ath_hal_setdiversity(ah, (sc->sc_diversity != 0));
- 	ath_hal_setdefantenna(ah, antenna);
-+	ath_hal_setantennaswitch(ah, sc->sc_diversity ? 0 : antenna);
- 	if (sc->sc_defant != antenna)
- 		sc->sc_stats.ast_ant_defswitch++;
- 	sc->sc_defant = antenna;
-@@ -11160,7 +11133,7 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 					break;
- 				}
- 				sc->sc_diversity = val;
--				ath_hal_setdiversity(ah, val);
-+				ath_setdefantenna(sc, sc->sc_defant);
- 				break;
- 			case ATH_TXINTRPERIOD:
- 				/* XXX: validate? */
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -640,7 +640,6 @@ struct ath_softc {
- 	spinlock_t sc_hal_lock;                 /* hardware access lock */
- 	struct ath_ratectrl *sc_rc;		/* tx rate control support */
- 	struct ath_tx99 *sc_tx99; 		/* tx99 support */
--	void (*sc_setdefantenna)(struct ath_softc *, u_int);
- 	const struct ath_hw_detect *sc_hwinfo;
- 
- 	unsigned int 	sc_invalid:1;		/* being detached */
diff --git a/package/madwifi/patches/421-channel_handling.patch b/package/madwifi/patches/421-channel_handling.patch
deleted file mode 100644
index 2a8ec27ce3..0000000000
--- a/package/madwifi/patches/421-channel_handling.patch
+++ /dev/null
@@ -1,1351 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -148,7 +148,6 @@ static int ath_key_set(struct ieee80211v
- static void ath_key_update_begin(struct ieee80211vap *);
- static void ath_key_update_end(struct ieee80211vap *);
- static void ath_mode_init(struct net_device *);
--static void ath_setslottime(struct ath_softc *);
- static void ath_updateslot(struct net_device *);
- static int ath_beaconq_setup(struct ath_softc *);
- static int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *);
-@@ -240,7 +239,7 @@ static void ath_setup_stationkey(struct
- static void ath_setup_stationwepkey(struct ieee80211_node *);
- static void ath_setup_keycacheslot(struct ath_softc *, struct ieee80211_node *);
- static void ath_newassoc(struct ieee80211_node *, int);
--static int ath_getchannels(struct net_device *, u_int, HAL_BOOL, HAL_BOOL);
-+static int ath_getchannels(struct net_device *);
- static void ath_led_event(struct ath_softc *, int);
- static void ath_update_txpow(struct ath_softc *);
- 
-@@ -265,7 +264,6 @@ static int ath_change_mtu(struct net_dev
- static int ath_ioctl(struct net_device *, struct ifreq *, int);
- 
- static int ath_rate_setup(struct net_device *, u_int);
--static void ath_setup_subrates(struct net_device *);
- #ifdef ATH_SUPERG_XR
- static int ath_xr_rate_setup(struct net_device *);
- static void ath_grppoll_txq_setup(struct ath_softc *, int, int);
-@@ -387,8 +385,6 @@ static void ath_fetch_idle_time(struct a
- 
- /* calibrate every 30 secs in steady state but check every second at first. */
- static int ath_calinterval = ATH_SHORT_CALINTERVAL;
--static int ath_countrycode = CTRY_DEFAULT;	/* country code */
--static int ath_outdoor = AH_FALSE;		/* enable outdoor use */
- static int ath_xchanmode = AH_TRUE;		/* enable extended channels */
- static int ath_maxvaps = ATH_MAXVAPS_DEFAULT;   /* set default maximum vaps */
- static int bstuck_thresh = BSTUCK_THRESH;       /* Stuck beacon count required for reset */
-@@ -396,9 +392,7 @@ static char *autocreate = NULL;
- static char *ratectl = DEF_RATE_CTL;
- static int rfkill = 0;
- static int tpc = 1;
--static int countrycode = -1;
- static int maxvaps = -1;
--static int outdoor = -1;
- static int xchanmode = -1;
- #include "ath_wprobe.c"
- static int beacon_cal = 1;
-@@ -437,9 +431,7 @@ static struct notifier_block ath_event_b
- 
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
- MODULE_PARM(beacon_cal, "i");
--MODULE_PARM(countrycode, "i");
- MODULE_PARM(maxvaps, "i");
--MODULE_PARM(outdoor, "i");
- MODULE_PARM(xchanmode, "i");
- MODULE_PARM(rfkill, "i");
- #ifdef ATH_CAP_TPC
-@@ -451,9 +443,7 @@ MODULE_PARM(ratectl, "s");
- #else
- #include <linux/moduleparam.h>
- module_param(beacon_cal, int, 0600);
--module_param(countrycode, int, 0600);
- module_param(maxvaps, int, 0600);
--module_param(outdoor, int, 0600);
- module_param(xchanmode, int, 0600);
- module_param(rfkill, int, 0600);
- #ifdef ATH_CAP_TPC
-@@ -463,9 +453,7 @@ module_param(bstuck_thresh, int, 0600);
- module_param(autocreate, charp, 0600);
- module_param(ratectl, charp, 0600);
- #endif
--MODULE_PARM_DESC(countrycode, "Override default country code");
- MODULE_PARM_DESC(maxvaps, "Maximum VAPs");
--MODULE_PARM_DESC(outdoor, "Enable/disable outdoor use");
- MODULE_PARM_DESC(xchanmode, "Enable/disable extended channel mode");
- MODULE_PARM_DESC(rfkill, "Enable/disable RFKILL capability");
- #ifdef ATH_CAP_TPC
-@@ -531,6 +519,50 @@ MODULE_PARM_DESC(ieee80211_debug, "Load-
- 				(bssid)[0] |= (((id) << 2) | 0x02);	\
- 		} while (0)
- 
-+static inline int ath_chan2mode(struct ieee80211_channel *c)
-+{
-+	if (IEEE80211_IS_CHAN_HALF(c))
-+		return ATH_MODE_HALF;
-+	else if (IEEE80211_IS_CHAN_QUARTER(c))
-+		return ATH_MODE_QUARTER;
-+	else
-+		return ieee80211_chan2mode(c);
-+}
-+
-+static inline int rate_hal2ieee(int dot11Rate, int f)
-+{
-+	int flag = dot11Rate & ~(IEEE80211_RATE_VAL);
-+	dot11Rate &= IEEE80211_RATE_VAL;
-+
-+	if (f == 4) { /* Quarter */
-+		if (dot11Rate == 4)
-+			return 18 | flag;
-+	}
-+	return (dot11Rate * f) | flag;
-+}
-+
-+static inline int rate_factor(int mode)
-+{
-+	int f;
-+
-+	/*
-+	 * NB: Fix up rates. HAL returns half or quarter dot11Rates,
-+	 * while the stack deals with full rates only
-+	 */
-+	switch(mode) {
-+		case ATH_MODE_HALF:
-+			f = 2;
-+			break;
-+		case ATH_MODE_QUARTER:
-+			f = 4;
-+			break;
-+		default:
-+			f = 1;
-+			break;
-+	}
-+	return f;
-+}
-+
- /* Initialize ath_softc structure */
- 
- int
-@@ -647,14 +679,6 @@ ath_attach(u_int16_t devid, struct net_d
- 	for (i = 0; i < sc->sc_keymax; i++)
- 		ath_hal_keyreset(ah, i);
- 
--	/*
--	 * Collect the channel list using the default country
--	 * code and including outdoor channels.  The 802.11 layer
--	 * is responsible for filtering this list based on settings
--	 * like the phy mode.
--	 */
--	if (countrycode != -1)
--		ath_countrycode = countrycode;
- 	if (maxvaps != -1) {
- 		ath_maxvaps = maxvaps;
- 		if (ath_maxvaps < ATH_MAXVAPS_MIN)
-@@ -662,17 +686,14 @@ ath_attach(u_int16_t devid, struct net_d
- 		else if (ath_maxvaps > ATH_MAXVAPS_MAX)
- 			ath_maxvaps = ATH_MAXVAPS_MAX;
- 	}
--	if (outdoor != -1)
--		ath_outdoor = outdoor;
- 	if (xchanmode != -1)
- 		ath_xchanmode = xchanmode;
--	error = ath_getchannels(dev, ath_countrycode,
--			ath_outdoor, ath_xchanmode);
-+	error = ath_getchannels(dev);
- 	if (error != 0)
- 		goto bad;
- 
--	ic->ic_country_code = ath_countrycode;
--	ic->ic_country_outdoor = ath_outdoor;
-+	ic->ic_country_code = CTRY_DEFAULT;
-+	ic->ic_country_outdoor = 0;
- 
- 	IPRINTF(sc, "Switching rfkill capability %s\n",
- 		rfkill ? "on" : "off");
-@@ -686,9 +707,8 @@ ath_attach(u_int16_t devid, struct net_d
- 	ath_rate_setup(dev, IEEE80211_MODE_11G);
- 	ath_rate_setup(dev, IEEE80211_MODE_TURBO_A);
- 	ath_rate_setup(dev, IEEE80211_MODE_TURBO_G);
--
--	/* Setup for half/quarter rates */
--	ath_setup_subrates(dev);
-+	ath_rate_setup(dev, ATH_MODE_HALF);
-+	ath_rate_setup(dev, ATH_MODE_QUARTER);
- 
- 	/* NB: setup here so ath_rate_update is happy */
- 	ath_setcurmode(sc, IEEE80211_MODE_11A);
-@@ -908,10 +928,6 @@ ath_attach(u_int16_t devid, struct net_d
- 			IEEE80211_ATHC_COMP : 0);
- #endif
- 
--#ifdef ATH_SUPERG_DYNTURBO
--	ic->ic_ath_cap |= (ath_hal_turboagsupported(ah, ath_countrycode) ? 
--			(IEEE80211_ATHC_TURBOP | IEEE80211_ATHC_AR) : 0);
--#endif
- #ifdef ATH_SUPERG_XR
- 	ic->ic_ath_cap |= (ath_hal_xrsupported(ah) ? IEEE80211_ATHC_XR : 0);
- #endif
-@@ -4470,17 +4486,17 @@ ath_mode_init(struct net_device *dev)
-  * Set the slot time based on the current setting.
-  */
- static void
--ath_setslottime(struct ath_softc *sc)
-+ath_settiming(struct ath_softc *sc)
- {
--	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc->sc_ah;
-+	u_int offset = getTimingOffset(sc);
- 
--	if (sc->sc_slottimeconf > 0) /* manual override */
--		ath_hal_setslottime(ah, sc->sc_slottimeconf);
--	else if (ic->ic_flags & IEEE80211_F_SHSLOT)
--		ath_hal_setslottime(ah, HAL_SLOT_TIME_9);
--	else
--		ath_hal_setslottime(ah, HAL_SLOT_TIME_20);
-+	if (sc->sc_slottimeconf > 0)
-+		ath_hal_setslottime(ah, offset + sc->sc_slottimeconf);
-+	if (sc->sc_acktimeconf > 0)
-+		ath_hal_setacktimeout(ah, 2 * offset + sc->sc_acktimeconf);
-+	if (sc->sc_ctstimeconf > 0)
-+		ath_hal_setctstimeout(ah, 2 * offset + sc->sc_ctstimeconf);
- 	sc->sc_updateslot = OK;
- }
- 
-@@ -4502,7 +4518,7 @@ ath_updateslot(struct net_device *dev)
- 	if (ic->ic_opmode == IEEE80211_M_HOSTAP)
- 		sc->sc_updateslot = UPDATE;
- 	else if (dev->flags & IFF_RUNNING)
--		ath_setslottime(sc);
-+		ath_settiming(sc);
- }
- 
- #ifdef ATH_SUPERG_DYNTURBO
-@@ -5346,7 +5362,7 @@ ath_beacon_send(struct ath_softc *sc, in
- 		sc->sc_updateslot = COMMIT;	/* commit next beacon */
- 		sc->sc_slotupdate = slot;
- 	} else if ((sc->sc_updateslot == COMMIT) && (sc->sc_slotupdate == slot))
--		ath_setslottime(sc);		/* commit change to hardware */
-+		ath_settiming(sc);		/* commit change to hardware */
- 
- 	if (bfaddr != 0) {
- 		/*
-@@ -7802,12 +7818,14 @@ ath_get_ivlen(struct ieee80211_key *k)
-  * Get transmit rate index using rate in Kbps
-  */
- static __inline int
--ath_tx_findindex(const HAL_RATE_TABLE *rt, int rate)
-+ath_tx_findindex(struct ath_softc *sc, const HAL_RATE_TABLE *rt, int rate)
- {
- 	unsigned int i, ndx = 0;
-+	int f;
- 
-+	f = rate_factor(sc->sc_curmode);
- 	for (i = 0; i < rt->rateCount; i++) {
--		if (rt->info[i].rateKbps == rate) {
-+		if ((rt->info[i].rateKbps * f) == rate) {
- 			ndx = i;
- 			break;
- 		}
-@@ -8100,7 +8118,7 @@ ath_tx_start(struct net_device *dev, str
- 		atype = HAL_PKT_TYPE_NORMAL;		/* default */
- 
- 		if (ismcast) {
--			rix = ath_tx_findindex(rt, vap->iv_mcast_rate);
-+			rix = ath_tx_findindex(sc, rt, vap->iv_mcast_rate);
- 			txrate = rt->info[rix].rateCode;
- 			if (shortPreamble)
- 				txrate |= rt->info[rix].shortPreamble;
-@@ -9067,7 +9085,7 @@ ath_chan_change(struct ath_softc *sc, st
- 	struct net_device *dev = sc->sc_dev;
- 	enum ieee80211_phymode mode;
- 
--	mode = ieee80211_chan2mode(chan);
-+	mode = ath_chan2mode(chan);
- 
- 	ath_rate_setup(dev, mode);
- 	ath_setcurmode(sc, mode);
-@@ -10124,8 +10142,7 @@ ath_newassoc(struct ieee80211_node *ni,
- }
- 
- static int
--ath_getchannels(struct net_device *dev, u_int cc,
--	HAL_BOOL outdoor, HAL_BOOL xchanmode)
-+ath_getchannels(struct net_device *dev)
- {
- 	struct ath_softc *sc = dev->priv;
- 	struct ieee80211com *ic = &sc->sc_ic;
-@@ -10139,17 +10156,31 @@ ath_getchannels(struct net_device *dev,
- 		EPRINTF(sc, "Insufficient memory for channel table!\n");
- 		return -ENOMEM;
- 	}
-+
-+restart:
- 	if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan,
- 	    ic->ic_regclassids, IEEE80211_REGCLASSIDS_MAX, &ic->ic_nregclass,
--	    cc, HAL_MODE_ALL, outdoor, xchanmode)) {
-+	    ic->ic_country_code, HAL_MODE_ALL, ic->ic_country_outdoor, ath_xchanmode)) {
- 		u_int32_t rd;
- 
- 		ath_hal_getregdomain(ah, &rd);
- 		EPRINTF(sc, "Unable to collect channel list from HAL; "
--			"regdomain likely %u country code %u\n", rd, cc);
-+			"regdomain likely %u country code %u\n", rd, ic->ic_country_code);
-+		if ((ic->ic_country_code != CTRY_DEFAULT) ||
-+			(ic->ic_country_outdoor != 0)) {
-+			EPRINTF(sc, "Reverting to defaults\n");
-+			ic->ic_country_code = CTRY_DEFAULT;
-+			ic->ic_country_outdoor = 0;
-+			goto restart;
-+		}
- 		kfree(chans);
- 		return -EINVAL;
- 	}
-+#ifdef ATH_SUPERG_DYNTURBO
-+	ic->ic_ath_cap &= ~(IEEE80211_ATHC_TURBOP | IEEE80211_ATHC_AR);
-+	ic->ic_ath_cap |= (ath_hal_turboagsupported(ah, ic->ic_country_code) ?
-+			(IEEE80211_ATHC_TURBOP | IEEE80211_ATHC_AR) : 0);
-+#endif
- 	/*
- 	 * Convert HAL channels to ieee80211 ones.
- 	 */
-@@ -10395,7 +10426,7 @@ ath_xr_rate_setup(struct net_device *dev
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	const HAL_RATE_TABLE *rt;
- 	struct ieee80211_rateset *rs;
--	unsigned int i, maxrates;
-+	unsigned int i, j, maxrates;
- 	sc->sc_xr_rates = ath_hal_getratetable(ah, HAL_MODE_XR);
- 	rt = sc->sc_xr_rates;
- 	if (rt == NULL)
-@@ -10408,57 +10439,16 @@ ath_xr_rate_setup(struct net_device *dev
- 	} else
- 		maxrates = rt->rateCount;
- 	rs = &ic->ic_sup_xr_rates;
--	for (i = 0; i < maxrates; i++)
--		rs->rs_rates[i] = rt->info[i].dot11Rate;
--	rs->rs_nrates = maxrates;
-+	for (j = 0, i = 0; i < maxrates; i++) {
-+		if (!rt->info[i].valid)
-+			continue;
-+		rs->rs_rates[j++] = rt->info[i].dot11Rate;
-+	}
-+	rs->rs_nrates = j;
- 	return 1;
- }
- #endif
- 
--/* Setup half/quarter rate table support */
--static void
--ath_setup_subrates(struct net_device *dev)
--{
--	struct ath_softc *sc = dev->priv;
--	struct ath_hal *ah = sc->sc_ah;
--	struct ieee80211com *ic = &sc->sc_ic;
--	const HAL_RATE_TABLE *rt;
--	struct ieee80211_rateset *rs;
--	unsigned int i, maxrates;
--
--	sc->sc_half_rates = ath_hal_getratetable(ah, HAL_MODE_11A_HALF_RATE);
--	rt = sc->sc_half_rates;
--	if (rt != NULL) {
--		if (rt->rateCount > IEEE80211_RATE_MAXSIZE) {
--			DPRINTF(sc, ATH_DEBUG_ANY,
--				"The rate table is too small (%u > %u)\n",
--			       rt->rateCount, IEEE80211_RATE_MAXSIZE);
--			maxrates = IEEE80211_RATE_MAXSIZE;
--		} else
--			maxrates = rt->rateCount;
--		rs = &ic->ic_sup_half_rates;
--		for (i = 0; i < maxrates; i++)
--			rs->rs_rates[i] = rt->info[i].dot11Rate;
--		rs->rs_nrates = maxrates;
--	}
--
--	sc->sc_quarter_rates = ath_hal_getratetable(ah, HAL_MODE_11A_QUARTER_RATE);
--	rt = sc->sc_quarter_rates;
--	if (rt != NULL) {
--		if (rt->rateCount > IEEE80211_RATE_MAXSIZE) {
--			DPRINTF(sc, ATH_DEBUG_ANY,
--				"The rate table is too small (%u > %u)\n",
--			       rt->rateCount, IEEE80211_RATE_MAXSIZE);
--			maxrates = IEEE80211_RATE_MAXSIZE;
--		} else
--			maxrates = rt->rateCount;
--		rs = &ic->ic_sup_quarter_rates;
--		for (i = 0; i < maxrates; i++)
--			rs->rs_rates[i] = rt->info[i].dot11Rate;
--		rs->rs_nrates = maxrates;
--	}
--}
--
- static int
- ath_rate_setup(struct net_device *dev, u_int mode)
- {
-@@ -10467,7 +10457,7 @@ ath_rate_setup(struct net_device *dev, u
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	const HAL_RATE_TABLE *rt;
- 	struct ieee80211_rateset *rs;
--	unsigned int i, maxrates;
-+	unsigned int i, j, maxrates, f;
- 
- 	switch (mode) {
- 	case IEEE80211_MODE_11A:
-@@ -10485,6 +10475,12 @@ ath_rate_setup(struct net_device *dev, u
- 	case IEEE80211_MODE_TURBO_G:
- 		sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_108G);
- 		break;
-+	case ATH_MODE_HALF:
-+		sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11A_HALF_RATE);
-+		break;
-+	case ATH_MODE_QUARTER:
-+		sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11A_QUARTER_RATE);
-+		break;
- 	default:
- 		DPRINTF(sc, ATH_DEBUG_ANY, "Invalid mode %u\n", mode);
- 		return 0;
-@@ -10499,10 +10495,16 @@ ath_rate_setup(struct net_device *dev, u
- 		maxrates = IEEE80211_RATE_MAXSIZE;
- 	} else
- 		maxrates = rt->rateCount;
-+
-+	/* NB: quarter/half rate channels hijack the 11A rateset */
-+	if (mode >= IEEE80211_MODE_MAX)
-+		return 1;
-+
- 	rs = &ic->ic_sup_rates[mode];
- 	for (i = 0; i < maxrates; i++)
- 		rs->rs_rates[i] = rt->info[i].dot11Rate;
- 	rs->rs_nrates = maxrates;
-+
- 	return 1;
- }
- 
-@@ -10531,13 +10533,18 @@ ath_setcurmode(struct ath_softc *sc, enu
- 		{   0, 500, 130 },
- 	};
- 	const HAL_RATE_TABLE *rt;
--	unsigned int i, j;
-+	unsigned int i, j, f;
- 
-+	/*
-+	 * NB: Fix up rixmap. HAL returns half or quarter dot11Rates,
-+	 * while the stack deals with full rates only
-+	 */
-+	f = rate_factor(mode);
- 	memset(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
- 	rt = sc->sc_rates[mode];
- 	KASSERT(rt != NULL, ("no h/w rate set for phy mode %u", mode));
- 	for (i = 0; i < rt->rateCount; i++)
--		sc->sc_rixmap[rt->info[i].dot11Rate & IEEE80211_RATE_VAL] = i;
-+		sc->sc_rixmap[rate_hal2ieee(rt->info[i].dot11Rate, f) & IEEE80211_RATE_VAL] = i;
- 	memset(sc->sc_hwmap, 0, sizeof(sc->sc_hwmap));
- 	for (i = 0; i < 32; i++) {
- 		u_int8_t ix = rt->rateCodeToIndex[i];
-@@ -10547,7 +10554,7 @@ ath_setcurmode(struct ath_softc *sc, enu
- 			continue;
- 		}
- 		sc->sc_hwmap[i].ieeerate =
--			rt->info[ix].dot11Rate & IEEE80211_RATE_VAL;
-+			rate_hal2ieee(rt->info[ix].dot11Rate, f) & IEEE80211_RATE_VAL;
- 		if (rt->info[ix].shortPreamble ||
- 		    rt->info[ix].phy == IEEE80211_T_OFDM)
- 			sc->sc_hwmap[i].flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
-@@ -10948,9 +10955,106 @@ enum {
- 	ATH_MAXVAPS  		= 26,
- 	ATH_INTMIT			= 27,
- 	ATH_NOISE_IMMUNITY	= 28,
--	ATH_OFDM_WEAK_DET	= 29
-+	ATH_OFDM_WEAK_DET	= 29,
-+	ATH_CHANBW		= 30,
-+	ATH_OUTDOOR		= 31,
- };
- 
-+/*
-+ * perform the channel related sysctl, reload the channel list
-+ * and try to stay on the current frequency
-+ */
-+static int ath_sysctl_setchanparam(struct ath_softc *sc, unsigned long ctl, u_int val)
-+{
-+	struct ieee80211com *ic = &sc->sc_ic;
-+	struct ath_hal *ah = sc->sc_ah;
-+	struct ieee80211_channel *c = NULL;
-+	struct ieee80211vap *vap;
-+	u_int16_t freq = 0;
-+	struct ifreq ifr;
-+
-+	if (ic->ic_curchan != IEEE80211_CHAN_ANYC)
-+		freq = ic->ic_curchan->ic_freq;
-+
-+	switch(ctl) {
-+	case ATH_COUNTRYCODE:
-+		ic->ic_country_code = val;
-+		break;
-+	case ATH_OUTDOOR:
-+		ic->ic_country_outdoor = val;
-+		break;
-+	case ATH_CHANBW:
-+		switch(val) {
-+		case 0:
-+		case 5:
-+		case 10:
-+		case 20:
-+		case 40:
-+			if (ath_hal_setcapability(ah, HAL_CAP_CHANBW, 1, val, NULL) == AH_TRUE) {
-+				sc->sc_chanbw = val;
-+				break;
-+			}
-+		default:
-+			return -EINVAL;
-+		}
-+		break;
-+	}
-+
-+	if (ic->ic_curchan != IEEE80211_CHAN_ANYC)
-+		freq = ic->ic_curchan->ic_freq;
-+
-+	/* clear out any old state */
-+	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+		vap->iv_des_mode = IEEE80211_MODE_AUTO;
-+		vap->iv_des_chan = IEEE80211_CHAN_ANYC;
-+	}
-+	ieee80211_scan_flush(ic);
-+
-+	IEEE80211_LOCK_IRQ(ic);
-+	ath_getchannels(sc->sc_dev);
-+	ieee80211_update_channels(ic, 0);
-+	if (freq)
-+		c = ieee80211_find_channel(ic, freq, IEEE80211_MODE_AUTO);
-+	if (!c)
-+		c = &ic->ic_channels[0];
-+	ic->ic_curchan = c;
-+	ic->ic_bsschan = c;
-+	ic->ic_curmode = IEEE80211_MODE_AUTO;
-+	IEEE80211_UNLOCK_IRQ(ic);
-+
-+	if (!(sc->sc_dev->flags & IFF_RUNNING)) {
-+		ic->ic_bsschan = IEEE80211_CHAN_ANYC;
-+		return 0;
-+	}
-+
-+#ifndef ifr_media
-+#define    ifr_media       ifr_ifru.ifru_ivalue
-+#endif
-+	memset(&ifr, 0, sizeof(ifr));
-+	ifr.ifr_media = ic->ic_media.ifm_cur->ifm_media & ~IFM_MMASK;
-+	ifr.ifr_media |= IFM_MAKEMODE(IEEE80211_MODE_AUTO);
-+	ifmedia_ioctl(ic->ic_dev, &ifr, &ic->ic_media, SIOCSIFMEDIA);
-+
-+	/* apply the channel to the hw */
-+	ath_set_channel(ic);
-+
-+	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+		struct net_device *dev = vap->iv_dev;
-+
-+		/* reactivate all active vaps */
-+		vap->iv_state = IEEE80211_S_SCAN;
-+		if ((vap->iv_opmode == IEEE80211_M_HOSTAP) ||
-+			(vap->iv_opmode == IEEE80211_M_MONITOR) ||
-+			(vap->iv_opmode == IEEE80211_M_WDS))
-+			ieee80211_new_state(vap, IEEE80211_S_RUN, 0);
-+		else
-+			ieee80211_new_state(vap, IEEE80211_S_INIT, -1);
-+	}
-+
-+	return 0;
-+}
-+
-+
- static int
- ath_sysctl_set_intmit(struct ath_softc *sc, long ctl, u_int val)
- {
-@@ -11029,6 +11133,7 @@ static int
- ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
- {
- 	struct ath_softc *sc = ctl->extra1;
-+	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc->sc_ah;
- 	u_int val;
- 	u_int tab_3_val[3];
-@@ -11052,25 +11157,34 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 				lenp, ppos);
- 		if (ret == 0) {
- 			switch ((long)ctl->extra2) {
-+			case ATH_REGDOMAIN:
-+				ath_hal_setregdomain(ah, val);
-+				break;
-+			case ATH_OUTDOOR:
-+			case ATH_COUNTRYCODE:
-+			case ATH_CHANBW:
-+				ret = ath_sysctl_setchanparam(sc, (long) ctl->extra2, val);
-+				break;
- 			case ATH_SLOTTIME:
--				if (val > 0) {
--					if (!ath_hal_setslottime(ah, val))
--						ret = -EINVAL;
--					else
--						sc->sc_slottimeconf = val;
--				} else {
--					/* disable manual override */
-+				if (val > 0)
-+					sc->sc_slottimeconf = val;
-+				else
- 					sc->sc_slottimeconf = 0;
--					ath_setslottime(sc);
--				}
-+				ath_settiming(sc);
- 				break;
- 			case ATH_ACKTIMEOUT:
--				if (!ath_hal_setacktimeout(ah, val))
--					ret = -EINVAL;
-+				if (val > 0)
-+					sc->sc_acktimeconf = val;
-+				else
-+					sc->sc_acktimeconf = 0;
-+				ath_settiming(sc);
- 				break;
- 			case ATH_CTSTIMEOUT:
--				if (!ath_hal_setctstimeout(ah, val))
--					ret = -EINVAL;
-+				if (val > 0)
-+					sc->sc_ctstimeconf = val;
-+				else
-+					sc->sc_ctstimeconf = 0;
-+				ath_settiming(sc);
- 				break;
- 			case ATH_SOFTLED:
- 				if (val != sc->sc_softled) {
-@@ -11223,6 +11337,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 		}
- 	} else {
- 		switch ((long)ctl->extra2) {
-+		case ATH_CHANBW:
-+			val = sc->sc_chanbw ?: 20;
-+			break;
- 		case ATH_SLOTTIME:
- 			val = ath_hal_getslottime(ah);
- 			break;
-@@ -11241,6 +11358,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 		case ATH_COUNTRYCODE:
- 			ath_hal_getcountrycode(ah, &val);
- 			break;
-+		case ATH_OUTDOOR:
-+			val = ic->ic_country_outdoor;
-+			break;
- 		case ATH_MAXVAPS:
- 			val = ath_maxvaps;
- 			break;
-@@ -11354,11 +11474,17 @@ static const ctl_table ath_sysctl_templa
- 	},
- 	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "countrycode",
--	  .mode		= 0444,
-+	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_COUNTRYCODE,
- 	},
- 	{ .ctl_name	= CTL_AUTO,
-+	  .procname	= "outdoor",
-+	  .mode		= 0644,
-+	  .proc_handler	= ath_sysctl_halparam,
-+	  .extra2	= (void *)ATH_OUTDOOR,
-+	},
-+	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "maxvaps",
- 	  .mode		= 0444,
- 	  .proc_handler	= ath_sysctl_halparam,
-@@ -11366,7 +11492,7 @@ static const ctl_table ath_sysctl_templa
- 	},
- 	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "regdomain",
--	  .mode		= 0444,
-+	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_REGDOMAIN,
- 	},
-@@ -11429,6 +11555,12 @@ static const ctl_table ath_sysctl_templa
- 	  .extra2	= (void *)ATH_ACKRATE,
- 	},
- 	{ .ctl_name	= CTL_AUTO,
-+	  .procname	= "channelbw",
-+	  .mode		= 0644,
-+	  .proc_handler	= ath_sysctl_halparam,
-+	  .extra2	= (void *)ATH_CHANBW,
-+	},
-+	{ .ctl_name	= CTL_AUTO,
- 	  .procname     = "rp",
- 	  .mode         = 0200,
- 	  .proc_handler = ath_sysctl_halparam,
-@@ -11669,13 +11801,6 @@ static ctl_table ath_static_sysctls[] =
- 	},
- #endif
- 	{ .ctl_name	= CTL_AUTO,
--	  .procname	= "countrycode",
--	  .mode		= 0444,
--	  .data		= &ath_countrycode,
--	  .maxlen	= sizeof(ath_countrycode),
--	  .proc_handler	= proc_dointvec
--	},
--	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "maxvaps",
- 	  .mode		= 0444,
- 	  .data		= &ath_maxvaps,
-@@ -11683,13 +11808,6 @@ static ctl_table ath_static_sysctls[] =
- 	  .proc_handler	= proc_dointvec
- 	},
- 	{ .ctl_name	= CTL_AUTO,
--	  .procname	= "outdoor",
--	  .mode		= 0444,
--	  .data		= &ath_outdoor,
--	  .maxlen	= sizeof(ath_outdoor),
--	  .proc_handler	= proc_dointvec
--	},
--	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "xchanmode",
- 	  .mode		= 0444,
- 	  .data		= &ath_xchanmode,
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -688,17 +688,18 @@ struct ath_softc {
- 	int8_t sc_ofdm_weak_det; /* OFDM weak frames detection, -1 == auto */
- 
- 	/* rate tables */
--	const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
-+#define ATH_MODE_HALF		(IEEE80211_MODE_MAX)
-+#define ATH_MODE_QUARTER	(IEEE80211_MODE_MAX + 1)
-+	const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX + 2];
- 	const HAL_RATE_TABLE *sc_currates;	/* current rate table */
- 	const HAL_RATE_TABLE *sc_xr_rates;	/* XR rate table */
--	const HAL_RATE_TABLE *sc_half_rates;	/* half rate table */
--	const HAL_RATE_TABLE *sc_quarter_rates;	/* quarter rate table */
- 	HAL_OPMODE sc_opmode;			/* current hal operating mode */
- 	enum ieee80211_phymode sc_curmode;	/* current phy mode */
- 	u_int sc_poweroffset;			/* hardware power offset */
- 	u_int16_t sc_curtxpow;			/* current tx power limit */
- 	u_int16_t sc_curaid;			/* current association id */
- 	HAL_CHANNEL sc_curchan;			/* current h/w channel */
-+	u_int8_t sc_chanbw;				/* channel bandwidth */
- 	u_int8_t sc_curbssid[IEEE80211_ADDR_LEN];
- 	u_int8_t	sc_rixmap[256];			/* IEEE to h/w rate table ix */
- 	struct {
-@@ -809,6 +810,8 @@ struct ath_softc {
- 	u_int32_t sc_dturbo_bw_turbo;		/* bandwidth threshold */
- #endif
- 	u_int sc_slottimeconf;			/* manual override for slottime */
-+	u_int sc_acktimeconf;			/* manual override for acktime */
-+	u_int sc_ctstimeconf;			/* manual override for ctstime */
- 
- 	struct timer_list sc_dfs_excl_timer;	/* mark expiration timer task */
- 	struct timer_list sc_dfs_cac_timer;	/* dfs wait timer */
-@@ -827,6 +830,7 @@ struct ath_softc {
- 	int sc_rp_num;
- 	int sc_rp_min;
- 	HAL_BOOL (*sc_rp_analyse)(struct ath_softc *sc);
-+	struct ATH_TQ_STRUCT sc_refresh_tq;
- 	struct ATH_TQ_STRUCT sc_rp_tq;
- 	
- 	int sc_rp_ignored;			/* if set, we ignored all 
-@@ -942,6 +946,48 @@ int ar_device(int devid);
- 	  DEV_NAME(_v->iv_ic->ic_dev))
- 
- void ath_radar_detected(struct ath_softc *sc, const char* message);
-+static inline u_int getTimingOffset(struct ath_softc *sc)
-+{
-+	struct ieee80211com *ic = &sc->sc_ic;
-+	u_int usec = 9;
-+	if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
-+		usec = 20;
-+		if (ic->ic_flags & IEEE80211_F_SHSLOT)
-+			usec = 9;
-+	} else if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
-+		usec = 9;
-+
-+	if (IEEE80211_IS_CHAN_TURBO(ic->ic_curchan))
-+		usec = 6;
-+
-+	if (IEEE80211_IS_CHAN_HALF(ic->ic_curchan))
-+		usec = 13;
-+	else if (IEEE80211_IS_CHAN_QUARTER(ic->ic_curchan))
-+		usec = 21;
-+	return usec;
-+}
-+
-+static inline void ath_get_timings(struct ath_softc *sc, u_int *t_slot, u_int *t_sifs, u_int *t_difs)
-+{
-+	struct ieee80211_channel *c = sc->sc_ic.ic_curchan;
-+
-+	*t_slot = getTimingOffset(sc) + sc->sc_slottimeconf;
-+
-+	if (IEEE80211_IS_CHAN_HALF(c)) {
-+		*t_sifs = 32;
-+		*t_difs = 56;
-+	} else if (IEEE80211_IS_CHAN_QUARTER(c)) {
-+		*t_sifs = 64;
-+		*t_difs = 112;
-+	} else if (IEEE80211_IS_CHAN_TURBO(c)) {
-+		*t_sifs = 8;
-+		*t_difs = 28;
-+	} else {
-+		*t_sifs = 16;
-+		*t_difs = 28;
-+	}
-+}
-+
- 
- struct ath_hw_detect {
- 	const char *vendor_name;
---- a/tools/athctrl.c
-+++ b/tools/athctrl.c
-@@ -118,7 +118,7 @@ CMD(athctrl)(int argc, char *argv[])
- 	}
- 
- 	if (distance >= 0) {
--	    	int slottime = 9 + (distance / 300) + ((distance % 300) ? 1 : 0);
-+		int slottime = (distance / 300) + ((distance % 300) ? 1 : 0);
- 		int acktimeout = slottime * 2 + 3;
- 		int ctstimeout = slottime * 2 + 3;
- 
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -243,34 +243,17 @@ static const  struct country_code_to_str
- 	{CTRY_ZIMBABWE,             "ZW"}
- };
- 
--int
--ieee80211_ifattach(struct ieee80211com *ic)
-+void ieee80211_update_channels(struct ieee80211com *ic, int init)
- {
--	struct net_device *dev = ic->ic_dev;
- 	struct ieee80211_channel *c;
-+	struct ieee80211vap *vap;
- 	struct ifmediareq imr;
-+	int ext = 0;
- 	int i;
- 
--	_MOD_INC_USE(THIS_MODULE, return -ENODEV);
--
--	/*
--	 * Pick an initial operating mode until we have a vap
--	 * created to lock it down correctly.  This is only
--	 * drivers have something defined for configuring the
--	 * hardware at startup.
--	 */
--	ic->ic_opmode = IEEE80211_M_STA;	/* everyone supports this */
--
--	/*
--	 * Fill in 802.11 available channel set, mark
--	 * all available channels as active, and pick
--	 * a default channel if not already specified.
--	 */
--	KASSERT(0 < ic->ic_nchans && ic->ic_nchans < IEEE80211_CHAN_MAX,
--		("invalid number of channels specified: %u", ic->ic_nchans));
- 	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
--	ic->ic_modecaps |= 1 << IEEE80211_MODE_AUTO;
- 	ic->ic_max_txpower = IEEE80211_TXPOWER_MIN;
-+	ic->ic_modecaps = 1 << IEEE80211_MODE_AUTO;
- 
- 	for (i = 0; i < ic->ic_nchans; i++) {
- 		c = &ic->ic_channels[i];
-@@ -298,6 +281,8 @@ ieee80211_ifattach(struct ieee80211com *
- 			ic->ic_modecaps |= 1 << IEEE80211_MODE_TURBO_A;
- 		if (IEEE80211_IS_CHAN_108G(c))
- 			ic->ic_modecaps |= 1 << IEEE80211_MODE_TURBO_G;
-+		if (IEEE80211_IS_CHAN_HALF(c) || IEEE80211_IS_CHAN_QUARTER(c))
-+			ext = 1;
- 	}
- 	/* Initialize candidate channels to all available */
- 	memcpy(ic->ic_chan_active, ic->ic_chan_avail,
-@@ -311,11 +296,59 @@ ieee80211_ifattach(struct ieee80211com *
- 	 * When 11g is supported, force the rate set to
- 	 * include basic rates suitable for a mixed b/g bss.
- 	 */
--	if (ic->ic_modecaps & (1 << IEEE80211_MODE_11G))
-+	if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11G)) && !ext)
- 		ieee80211_set11gbasicrates(
- 			&ic->ic_sup_rates[IEEE80211_MODE_11G],
- 			IEEE80211_MODE_11G);
- 
-+	if (init)
-+		return;
-+
-+	ifmedia_removeall(&ic->ic_media);
-+	ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, NULL, NULL);
-+	ieee80211com_media_status(ic->ic_dev, &imr);
-+	ifmedia_set(&ic->ic_media, imr.ifm_active);
-+
-+	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
-+		struct ieee80211vap *avp;
-+		TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
-+			(void) ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps, NULL, NULL);
-+			ieee80211_media_status(vap->iv_dev, &imr);
-+			ifmedia_set(&vap->iv_media, imr.ifm_active);
-+		}
-+		(void) ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps, NULL, NULL);
-+		ieee80211_media_status(vap->iv_dev, &imr);
-+		ifmedia_set(&vap->iv_media, imr.ifm_active);
-+	}
-+}
-+EXPORT_SYMBOL(ieee80211_update_channels);
-+
-+int
-+ieee80211_ifattach(struct ieee80211com *ic)
-+{
-+	struct net_device *dev = ic->ic_dev;
-+	struct ieee80211_channel *c;
-+	struct ifmediareq imr;
-+
-+	_MOD_INC_USE(THIS_MODULE, return -ENODEV);
-+
-+	/*
-+	 * Pick an initial operating mode until we have a vap
-+	 * created to lock it down correctly.  This is only
-+	 * drivers have something defined for configuring the
-+	 * hardware at startup.
-+	 */
-+	ic->ic_opmode = IEEE80211_M_STA;	/* everyone supports this */
-+
-+	/*
-+	 * Fill in 802.11 available channel set, mark
-+	 * all available channels as active, and pick
-+	 * a default channel if not already specified.
-+	 */
-+	KASSERT(0 < ic->ic_nchans && ic->ic_nchans < IEEE80211_CHAN_MAX,
-+		("invalid number of channels specified: %u", ic->ic_nchans));
-+	ieee80211_update_channels(ic, 1);
-+
- 	/* Setup initial channel settings */
- 	ic->ic_bsschan = IEEE80211_CHAN_ANYC;
- 	/* Arbitrarily pick the first channel */
-@@ -327,6 +360,7 @@ ieee80211_ifattach(struct ieee80211com *
- 	/* Enable WME by default, if we're capable. */
- 	if (ic->ic_caps & IEEE80211_C_WME)
- 		ic->ic_flags |= IEEE80211_F_WME;
-+
- 	(void) ieee80211_setmode(ic, ic->ic_curmode);
- 
- 	/* Store default beacon interval, as nec. */
-@@ -763,7 +797,8 @@ ieee80211_media_setup(struct ieee80211co
- 	struct ieee80211_rateset allrates;
- 
- 	/* Fill in media characteristics. */
--	ifmedia_init(media, 0, media_change, media_stat);
-+	if (media_change || media_stat)
-+		ifmedia_init(media, 0, media_change, media_stat);
- 	maxrate = 0;
- 	memset(&allrates, 0, sizeof(allrates));
- 
-@@ -793,7 +828,7 @@ ieee80211_media_setup(struct ieee80211co
- 			ADD(media, IFM_AUTO, mopt | IFM_IEEE80211_WDS);
- 		if (mode == IEEE80211_MODE_AUTO)
- 			continue;
--		rs = &ic->ic_sup_rates[mode];
-+		rs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)];
- 
- 		for (i = 0; i < rs->rs_nrates; i++) {
- 			rate = rs->rs_rates[i];
-@@ -1207,7 +1242,7 @@ ieee80211_announce(struct ieee80211com *
- 		if ((ic->ic_modecaps & (1 << mode)) == 0)
- 			continue;
- 		if_printf(dev, "%s rates: ", ieee80211_phymode_name[mode]);
--		rs = &ic->ic_sup_rates[mode];
-+		rs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)];
- 		for (i = 0; i < rs->rs_nrates; i++) {
- 			rate = rs->rs_rates[i];
- 			mword = ieee80211_rate2media(ic, rate, mode);
-@@ -1417,7 +1452,7 @@ ieee80211com_media_change(struct net_dev
- 			 * now so drivers have a consistent state.
- 			 */
- 			KASSERT(vap->iv_bss != NULL, ("no bss node"));
--			vap->iv_bss->ni_rates = ic->ic_sup_rates[newphymode];
-+			vap->iv_bss->ni_rates = ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, newphymode)];
- 		}
- 		error = -ENETRESET;
- 	}
-@@ -1435,7 +1470,7 @@ findrate(struct ieee80211com *ic, enum i
- {
- #define	IEEERATE(_ic,_m,_i) \
- 	((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)
--	int i, nrates = ic->ic_sup_rates[mode].rs_nrates;
-+	int i, nrates = ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)].rs_nrates;
- 	for (i = 0; i < nrates; i++)
- 		if (IEEERATE(ic, mode, i) == rate)
- 			return i;
-@@ -1877,11 +1912,6 @@ ieee80211_build_countryie(struct ieee802
- 			if (ieee80211_chan2mode(c) != curmode_noturbo)
- 				continue;
- 
--			/* Skip half/quarter rate channels */
--			if (IEEE80211_IS_CHAN_HALF(c) ||
--			    IEEE80211_IS_CHAN_QUARTER(c))
--				continue;
--
- 			if (*cur_runlen == 0) {
- 				(*cur_runlen)++;
- 				*cur_pow = c->ic_maxregpower;
-@@ -1915,7 +1945,7 @@ void
- ieee80211_build_sc_ie(struct ieee80211com *ic)
- {
- 	struct ieee80211_ie_sc *ie = &ic->ic_sc_ie;
--	int i, j;
-+	int i, j, k;
- 	struct ieee80211_channel *c;
- 	u_int8_t prevchan;
- 
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -336,8 +336,6 @@ struct ieee80211com {
- 	u_int8_t ic_nopened;			/* VAPs been opened */
- 	struct ieee80211_rateset ic_sup_rates[IEEE80211_MODE_MAX];
- 	struct ieee80211_rateset ic_sup_xr_rates;
--	struct ieee80211_rateset ic_sup_half_rates;
--	struct ieee80211_rateset ic_sup_quarter_rates;
- 	u_int16_t ic_modecaps;			/* set of mode capabilities */
- 	u_int16_t ic_curmode;			/* current mode */
- 	u_int16_t ic_lintval;			/* beacon interval */
-@@ -714,6 +712,7 @@ MALLOC_DECLARE(M_80211_VAP);
- 
- int ieee80211_ifattach(struct ieee80211com *);
- void ieee80211_ifdetach(struct ieee80211com *);
-+void ieee80211_update_channels(struct ieee80211com *ic, int);
- int ieee80211_vap_setup(struct ieee80211com *, struct net_device *,
- 	const char *, int, int, struct ieee80211vap *);
- int ieee80211_vap_attach(struct ieee80211vap *, ifm_change_cb_t, ifm_stat_cb_t);
-@@ -793,6 +792,23 @@ ieee80211_anyhdrspace(struct ieee80211co
- 	return size;
- }
- 
-+static __inline int
-+ieee80211_chan2ratemode(struct ieee80211_channel *c, int mode)
-+{
-+	if (mode == -1)
-+		mode = ieee80211_chan2mode(c);
-+
-+	/*
-+	 * Use 11a rateset for half/quarter to restrict things
-+	 * to pure OFDM
-+	 */
-+	if (IEEE80211_IS_CHAN_HALF(c) ||
-+		IEEE80211_IS_CHAN_QUARTER(c))
-+		return IEEE80211_MODE_11A;
-+
-+	return mode;
-+}
-+
- /* Macros to print MAC address used in 802.11 headers */
- 
- #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -287,7 +287,7 @@ ieee80211_node_set_chan(struct ieee80211
- 		ni->ni_rates = ic->ic_sup_xr_rates;
- 	else
- #endif
--	ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2mode(chan)];
-+	ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2ratemode(chan, -1)];
- }
- 
- static __inline void
-@@ -387,6 +387,8 @@ ieee80211_create_ibss(struct ieee80211va
- 	ic->ic_bsschan = chan;
- 	ieee80211_node_set_chan(ic, ni);
- 	ic->ic_curmode = ieee80211_chan2mode(chan);
-+	ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2ratemode(chan, -1)];
-+
- 	spin_lock_irqsave(&channel_lock, flags);
- 	ieee80211_scan_set_bss_channel(ic, ic->ic_bsschan);
- 	spin_unlock_irqrestore(&channel_lock, flags);
-@@ -394,14 +396,8 @@ ieee80211_create_ibss(struct ieee80211va
- 	/* Update country ie information */
- 	ieee80211_build_countryie(ic);
- 
--	if (IEEE80211_IS_CHAN_HALF(chan)) {
--		ni->ni_rates = ic->ic_sup_half_rates;
--	} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
--		ni->ni_rates = ic->ic_sup_quarter_rates;
--	}
--
--	if ((vap->iv_flags & IEEE80211_F_PUREG) &&
--		IEEE80211_IS_CHAN_ANYG(chan)) {
-+	if ((ieee80211_chan2ratemode(chan, -1) != IEEE80211_MODE_11A) &&
-+		IEEE80211_IS_CHAN_ANYG(chan) && (vap->iv_flags & IEEE80211_F_PUREG)) {
- 		ieee80211_setpuregbasicrates(&ni->ni_rates);
- 	}
- 
---- a/net80211/ieee80211_scan_sta.c
-+++ b/net80211/ieee80211_scan_sta.c
-@@ -490,12 +490,7 @@ check_rate(struct ieee80211vap *vap, con
- 
- 	okrate = badrate = fixedrate = 0;
- 
--	if (IEEE80211_IS_CHAN_HALF(se->se_chan))
--		srs = &ic->ic_sup_half_rates;
--	else if (IEEE80211_IS_CHAN_QUARTER(se->se_chan))
--		srs = &ic->ic_sup_quarter_rates;
--	else
--		srs = &ic->ic_sup_rates[ieee80211_chan2mode(se->se_chan)];
-+	srs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, -1)];
- 	nrs = se->se_rates[1];
- 	rs = se->se_rates + 2;
- 	fixedrate = IEEE80211_FIXED_RATE_NONE;
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -1676,8 +1676,8 @@ ieee80211_send_probereq(struct ieee80211
- 
- 	frm = ieee80211_add_ssid(frm, ssid, ssidlen);
- 	mode = ieee80211_chan2mode(ic->ic_curchan);
--	frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]);
--	frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]);
-+	frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)]);
-+	frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, mode)]);
- 
- 	if (optie != NULL) {
- 		memcpy(frm, optie, optielen);
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -404,7 +404,7 @@ ieee80211_fix_rate(struct ieee80211_node
- 
- 	error = 0;
- 	okrate = badrate = fixedrate = 0;
--	srs = &ic->ic_sup_rates[ieee80211_chan2mode(ni->ni_chan)];
-+	srs = &ic->ic_sup_rates[ieee80211_chan2ratemode(ic->ic_curchan, -1)];
- 	nrs = &ni->ni_rates;
- 	fixedrate = IEEE80211_FIXED_RATE_NONE;
- 	for (i = 0; i < nrs->rs_nrates;) {
-@@ -1407,6 +1407,7 @@ ieee80211_new_state(struct ieee80211vap
- 	IEEE80211_VAPS_UNLOCK_IRQ(ic);
- 	return rc;
- }
-+EXPORT_SYMBOL(ieee80211_new_state);
- 
- static int
- __ieee80211_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -195,31 +195,7 @@ calc_usecs_unicast_packet(struct ath_sof
- 			return 0;
- 		}
- 
--		/* XXX: Getting MAC/PHY level timings should be fixed for turbo
--		 * rates, and there is probably a way to get this from the
--		 * HAL... */
--		switch (rt->info[rix].phy) {
--		case IEEE80211_T_OFDM:
--#if 0
--			t_slot = 9;
--			t_sifs = 16;
--			t_difs = 28;
--			/* fall through */
--#endif
--		case IEEE80211_T_TURBO:
--			t_slot = 9;
--			t_sifs = 8;
--			t_difs = 28;
--			break;
--		case IEEE80211_T_DS:
--			/* Fall through to default */
--		default:
--			/* pg. 205 ieee.802.11.pdf */
--			t_slot = 20;
--			t_difs = 50;
--			t_sifs = 10;
--		}
--
-+		ath_get_timings(sc, &t_slot, &t_sifs, &t_difs);
- 		if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
- 		(rt->info[rix].phy == IEEE80211_T_OFDM)) {
- 			if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -172,26 +172,7 @@ calc_usecs_unicast_packet(struct ath_sof
- 	 * rates, and there is probably a way to get this from the
- 	 * hal...
- 	 */
--	switch (rt->info[rix].phy) {
--	case IEEE80211_T_OFDM:
--		t_slot = 9;
--		t_sifs = 16;
--		t_difs = 28;
--		/* fall through */
--	case IEEE80211_T_TURBO:
--		t_slot = 9;
--		t_sifs = 8;
--		t_difs = 28;
--		break;
--	case IEEE80211_T_DS:
--		/* fall through to default */
--	default:
--		/* pg 205 ieee.802.11.pdf */
--		t_slot = 20;
--		t_difs = 50;
--		t_sifs = 10;
--	}
--
-+	ath_get_timings(sc, &t_slot, &t_sifs, &t_difs);
- 	rts = cts = 0;
- 
- 	if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2142,7 +2142,7 @@ ieee80211_ioctl_setmode(struct net_devic
- 
- 		vap->iv_des_mode = mode;
- 		if (IS_UP_AUTO(vap))
--			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
-+			ieee80211_init(vap->iv_dev, 0);
- 
- 		retv = 0;
- 	}
-@@ -4090,46 +4090,60 @@ ieee80211_ioctl_getchanlist(struct net_d
- 	return 0;
- }
- 
-+static int alreadyListed(struct ieee80211req_chaninfo *chans, u_int16_t mhz)
-+{
-+	int i;
-+	for (i = 0; i < chans->ic_nchans; i++) {
-+		if (chans->ic_chans[i].ic_freq == mhz)
-+			return 1;
-+	}
-+	return 0;
-+}
-+
- static int
- ieee80211_ioctl_getchaninfo(struct net_device *dev,
--	struct iw_request_info *info, void *w, char *extra)
-+			    struct iw_request_info *info, void *w, char *extra)
- {
- 	struct ieee80211vap *vap = dev->priv;
- 	struct ieee80211com *ic = vap->iv_ic;
--	struct ieee80211req_chaninfo chans;
-+	struct ieee80211req_chaninfo *chans =
-+	    (struct ieee80211req_chaninfo *)extra;
-+
- 	u_int8_t reported[IEEE80211_CHAN_BYTES];	/* XXX stack usage? */
- 	int i;
- 
--	memset(&chans, 0, sizeof(chans));
--	memset(&reported, 0, sizeof(reported));
-+	memset(chans, 0, sizeof(*chans));
-+	memset(reported, 0, sizeof(reported));
- 	for (i = 0; i < ic->ic_nchans; i++) {
- 		const struct ieee80211_channel *c = &ic->ic_channels[i];
- 		const struct ieee80211_channel *c1 = c;
- 
--		if (isclr(reported, c->ic_ieee)) {
-+		if (!alreadyListed(chans, c->ic_freq)) {
- 			setbit(reported, c->ic_ieee);
- 
--			/* pick turbo channel over non-turbo channel, and
--			 * 11g channel over 11b channel */
- 			if (IEEE80211_IS_CHAN_A(c))
--				c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_TURBO_A);
-+				c1 = findchannel(ic, c->ic_freq,
-+						 IEEE80211_MODE_TURBO_A);
- 			if (IEEE80211_IS_CHAN_ANYG(c))
--				c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_TURBO_G);
-+				c1 = findchannel(ic, c->ic_freq,
-+						 IEEE80211_MODE_TURBO_G);
- 			else if (IEEE80211_IS_CHAN_B(c)) {
--				c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_TURBO_G);
-+				c1 = findchannel(ic, c->ic_freq,
-+						 IEEE80211_MODE_TURBO_G);
- 				if (!c1)
--					c1 = findchannel(ic, c->ic_ieee, IEEE80211_MODE_11G);
-+					c1 = findchannel(ic, c->ic_freq,
-+							 IEEE80211_MODE_11G);
- 			}
- 
- 			if (c1)
- 				c = c1;
--			/* Copy the entire structure, whereas it used to just copy a few fields */
--			memcpy(&chans.ic_chans[chans.ic_nchans], c, sizeof(struct ieee80211_channel));
--			if (++chans.ic_nchans >= IEEE80211_CHAN_MAX)
-+			chans->ic_chans[chans->ic_nchans].ic_ieee = c->ic_ieee;
-+			chans->ic_chans[chans->ic_nchans].ic_freq = c->ic_freq;
-+			chans->ic_chans[chans->ic_nchans].ic_flags = c->ic_flags;
-+			if (++chans->ic_nchans >= IEEE80211_CHAN_MAX)
- 				break;
- 		}
- 	}
--	memcpy(extra, &chans, sizeof(struct ieee80211req_chaninfo));
- 	return 0;
- }
- 
---- a/net80211/ieee80211_scan_ap.c
-+++ b/net80211/ieee80211_scan_ap.c
-@@ -512,12 +512,13 @@ pick_channel(struct ieee80211_scan_state
- 	int ss_last = ss->ss_last;
- 	struct ieee80211_channel *best;
- 	struct ap_state *as = ss->ss_priv;
--	struct channel chans[ss_last]; /* actually ss_last-1 is required */
-+	struct channel *chans; /* actually ss_last-1 is required */
- 	struct channel *c = NULL;
- 	struct pc_params params = { vap, ss, flags };
- 	int benefit = 0;
- 	int sta_assoc = 0;
- 
-+	chans = (struct channel *)kmalloc(ss_last*sizeof(struct channel),GFP_ATOMIC);
- 	for (i = 0; i < ss_last; i++) {
- 		chans[i].chan = ss->ss_chans[i];
- 		chans[i].orig = i;
-@@ -571,6 +572,7 @@ pick_channel(struct ieee80211_scan_state
- 				"%s: best: channel %u rssi %d\n",
- 				__func__, i, as->as_maxrssi[i]);
- 	}
-+	kfree(chans);
- 	return best;
- }
- 
-@@ -609,6 +611,7 @@ ap_end(struct ieee80211_scan_state *ss,
- 		res = 1; /* Do NOT restart scan */
- 	} else {
- 		struct ieee80211_scan_entry se;
-+		int i;
- 		/* XXX: notify all VAPs? */
- 		/* if this is a dynamic turbo frequency , start with normal 
- 		 * mode first */
-@@ -623,6 +626,11 @@ ap_end(struct ieee80211_scan_state *ss,
- 				return 0;
- 			}
- 		}
-+		for (i = (bestchan - &ic->ic_channels[0])/sizeof(*bestchan) + 1; i < ic->ic_nchans; i++) {
-+			if ((ic->ic_channels[i].ic_freq == bestchan->ic_freq) &&
-+				IEEE80211_IS_CHAN_ANYG(&ic->ic_channels[i]))
-+				bestchan = &ic->ic_channels[i];
-+		}
- 		memset(&se, 0, sizeof(se));
- 		se.se_chan = bestchan;
- 
---- a/tools/wlanconfig.c
-+++ b/tools/wlanconfig.c
-@@ -737,7 +737,7 @@ list_channels(const char *ifname, int al
- 	if (get80211priv(ifname, IEEE80211_IOCTL_GETCHANINFO, &chans, sizeof(chans)) < 0)
- 		errx(1, "unable to get channel information");
- 	if (!allchans) {
--		uint8_t active[32];
-+		uint8_t active[IEEE80211_CHAN_BYTES];
- 
- 		if (get80211priv(ifname, IEEE80211_IOCTL_GETCHANLIST, &active, sizeof(active)) < 0)
- 			errx(1, "unable to get active channel list");
---- a/net80211/ieee80211_scan.c
-+++ b/net80211/ieee80211_scan.c
-@@ -1044,6 +1044,7 @@ ieee80211_scan_assoc_fail(struct ieee802
- 		ss->ss_ops->scan_assoc_fail(ss, mac, reason);
- 	}
- }
-+EXPORT_SYMBOL(ieee80211_scan_flush);
- 
- /*
-  * Iterate over the contents of the scan cache.
---- a/ath/if_ath_hal_wrappers.h
-+++ b/ath/if_ath_hal_wrappers.h
-@@ -111,6 +111,11 @@ static inline HAL_BOOL ath_hal_getregdom
- 	return (ath_hal_getcapability(ah, HAL_CAP_REG_DMN, 0, destination) == HAL_OK);
- }
- 
-+static inline HAL_BOOL ath_hal_setregdomain(struct ath_hal *ah, u_int32_t v)
-+{
-+	return (ath_hal_setcapability(ah, HAL_CAP_REG_DMN, 0, v, NULL));
-+}
-+
- static inline HAL_BOOL ath_hal_gettkipmic(struct ath_hal *ah)
- {
- 	return (ath_hal_getcapability(ah, HAL_CAP_TKIP_MIC, 1, NULL) == HAL_OK);
diff --git a/package/madwifi/patches/422-confchange_reset.patch b/package/madwifi/patches/422-confchange_reset.patch
deleted file mode 100644
index 33040ae0dd..0000000000
--- a/package/madwifi/patches/422-confchange_reset.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -70,7 +70,8 @@
- 	(((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
- #define	IS_UP_AUTO(_vap) \
- 	(IS_UP((_vap)->iv_dev) && \
--	 (_vap)->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO)
-+	 (((_vap)->iv_opmode == IEEE80211_M_HOSTAP) || \
-+	 (_vap)->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO))
- #define	RESCAN	1
- 
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-@@ -283,7 +284,7 @@ ieee80211_ioctl_siwencode(struct net_dev
- 				vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
- 		}
- 	}
--	if ((error == 0) && IS_UP(vap->iv_dev)) {
-+	if ((error == 0) && IS_UP_AUTO(vap) && wepchange) {
- 		/*
- 		 * Device is up and running; we must kick it to
- 		 * effect the change.  If we're enabling/disabling
-@@ -291,8 +292,7 @@ ieee80211_ioctl_siwencode(struct net_dev
- 		 * so the 802.11 state machine is reset.  Otherwise
- 		 * the key state should have been updated above.
- 		 */
--		if (wepchange && IS_UP_AUTO(vap))
--			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
-+		ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
- 	}
- #ifdef ATH_SUPERG_XR
- 	/* set the same params on the xr vap device if exists */
diff --git a/package/madwifi/patches/423-phyerr_handling.patch b/package/madwifi/patches/423-phyerr_handling.patch
deleted file mode 100644
index 7f3cbafe23..0000000000
--- a/package/madwifi/patches/423-phyerr_handling.patch
+++ /dev/null
@@ -1,28 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -4391,13 +4391,12 @@ ath_key_update_end(struct ieee80211vap *
- static u_int32_t
- ath_calcrxfilter(struct ath_softc *sc)
- {
--#define	RX_FILTER_PRESERVE	(HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR)
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct net_device *dev = ic->ic_dev;
- 	struct ath_hal *ah = sc->sc_ah;
- 	u_int32_t rfilt;
- 
--	rfilt = (ath_hal_getrxfilter(ah) & RX_FILTER_PRESERVE) |
-+	rfilt = ath_hal_getrxfilter(ah) |
- 		 HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST |
- 		 HAL_RX_FILTER_MCAST;
- 	if (ic->ic_opmode != IEEE80211_M_STA)
-@@ -4416,9 +4415,8 @@ ath_calcrxfilter(struct ath_softc *sc)
- 	if (sc->sc_hasintmit && !sc->sc_needmib && ath_hal_getintmit(ah, NULL))
- 		rfilt |= HAL_RX_FILTER_PHYERR;
- 	if (sc->sc_curchan.privFlags & CHANNEL_DFS)
--		rfilt |= (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR);
-+		rfilt |= HAL_RX_FILTER_PHYRADAR;
- 	return rfilt;
--#undef RX_FILTER_PRESERVE
- }
- 
- /*
diff --git a/package/madwifi/patches/424-timing.patch b/package/madwifi/patches/424-timing.patch
deleted file mode 100644
index 8369db6185..0000000000
--- a/package/madwifi/patches/424-timing.patch
+++ /dev/null
@@ -1,764 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -382,6 +382,7 @@ static u_int32_t ath_set_clamped_maxtxpo
- static void ath_poll_disable(struct net_device *dev);
- static void ath_poll_enable(struct net_device *dev);
- static void ath_fetch_idle_time(struct ath_softc *sc);
-+static void ath_set_timing(struct ath_softc *sc);
- 
- /* calibrate every 30 secs in steady state but check every second at first. */
- static int ath_calinterval = ATH_SHORT_CALINTERVAL;
-@@ -1185,6 +1186,7 @@ ath_attach(u_int16_t devid, struct net_d
- 	sc->sc_intmit = -1;
- 	sc->sc_noise_immunity = -1;
- 	sc->sc_ofdm_weak_det = -1;
-+	sc->sc_coverage = 7; /* 2100 meters */
- 
- 	return 0;
- bad3:
-@@ -2673,6 +2675,7 @@ ath_init(struct net_device *dev)
- 	 */
- 	ath_chan_change(sc, ic->ic_curchan);
- 	ath_set_ack_bitrate(sc, sc->sc_ackrate);
-+	ath_set_timing(sc);
- 	dev->flags |= IFF_RUNNING;		/* we are ready to go */
- 	ieee80211_start_running(ic);		/* start all VAPs */
- #ifdef ATH_TX99_DIAG
-@@ -4484,17 +4487,52 @@ ath_mode_init(struct net_device *dev)
-  * Set the slot time based on the current setting.
-  */
- static void
--ath_settiming(struct ath_softc *sc)
-+ath_set_timing(struct ath_softc *sc)
- {
-+	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc->sc_ah;
--	u_int offset = getTimingOffset(sc);
-+	struct ath_timings *t = &sc->sc_timings;
-+	u_int offset = 9;
-+
-+	t->sifs = 16;
-+	if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
-+		offset = 20;
-+		if (ic->ic_flags & IEEE80211_F_SHSLOT)
-+			offset = 9;
-+	} else if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
-+		offset = 9;
-+	}
-+
-+	if (IEEE80211_IS_CHAN_TURBO(ic->ic_curchan)) {
-+		offset = 6;
-+		t->sifs = 8;
-+	} else if (IEEE80211_IS_CHAN_HALF(ic->ic_curchan)) {
-+		offset = 13;
-+		t->sifs = 32;
-+	} else if (IEEE80211_IS_CHAN_QUARTER(ic->ic_curchan)) {
-+		offset = 21;
-+		t->sifs = 64;
-+	}
-+
-+	t->slot = offset + sc->sc_coverage;
-+	t->ack = t->slot * 2 + 3;
-+	t->cts = t->slot * 2 + 3;
- 
- 	if (sc->sc_slottimeconf > 0)
--		ath_hal_setslottime(ah, offset + sc->sc_slottimeconf);
-+		t->slot = sc->sc_slottimeconf;
- 	if (sc->sc_acktimeconf > 0)
--		ath_hal_setacktimeout(ah, 2 * offset + sc->sc_acktimeconf);
-+		t->ack = sc->sc_acktimeconf;
- 	if (sc->sc_ctstimeconf > 0)
--		ath_hal_setctstimeout(ah, 2 * offset + sc->sc_ctstimeconf);
-+		t->cts = sc->sc_ctstimeconf;
-+
-+	t->difs = 2 * t->sifs + t->slot;
-+	t->eifs = t->sifs + t->difs + 3;
-+
-+	ath_hal_setslottime(ah, t->slot);
-+	ath_hal_setacktimeout(ah, t->ack);
-+	ath_hal_setctstimeout(ah, t->cts);
-+	ath_hal_seteifstime(ah, t->eifs);
-+
- 	sc->sc_updateslot = OK;
- }
- 
-@@ -4516,7 +4554,7 @@ ath_updateslot(struct net_device *dev)
- 	if (ic->ic_opmode == IEEE80211_M_HOSTAP)
- 		sc->sc_updateslot = UPDATE;
- 	else if (dev->flags & IFF_RUNNING)
--		ath_settiming(sc);
-+		ath_set_timing(sc);
- }
- 
- #ifdef ATH_SUPERG_DYNTURBO
-@@ -5360,7 +5398,7 @@ ath_beacon_send(struct ath_softc *sc, in
- 		sc->sc_updateslot = COMMIT;	/* commit next beacon */
- 		sc->sc_slotupdate = slot;
- 	} else if ((sc->sc_updateslot == COMMIT) && (sc->sc_slotupdate == slot))
--		ath_settiming(sc);		/* commit change to hardware */
-+		ath_set_timing(sc);		/* commit change to hardware */
- 
- 	if (bfaddr != 0) {
- 		/*
-@@ -9433,7 +9471,8 @@ ath_set_coverageclass(struct ieee80211co
- {
- 	struct ath_softc *sc = ic->ic_dev->priv;
- 
--	ath_hal_setcoverageclass(sc->sc_ah, ic->ic_coverageclass, 0);
-+	sc->sc_coverage = ic->ic_coverageclass * 3;
-+	ath_set_timing(sc);
- 
- 	return;
- }
-@@ -10956,6 +10995,7 @@ enum {
- 	ATH_OFDM_WEAK_DET	= 29,
- 	ATH_CHANBW		= 30,
- 	ATH_OUTDOOR		= 31,
-+	ATH_DISTANCE	= 32,
- };
- 
- /*
-@@ -11168,21 +11208,31 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 					sc->sc_slottimeconf = val;
- 				else
- 					sc->sc_slottimeconf = 0;
--				ath_settiming(sc);
-+				ath_set_timing(sc);
- 				break;
- 			case ATH_ACKTIMEOUT:
- 				if (val > 0)
- 					sc->sc_acktimeconf = val;
- 				else
- 					sc->sc_acktimeconf = 0;
--				ath_settiming(sc);
-+				ath_set_timing(sc);
- 				break;
- 			case ATH_CTSTIMEOUT:
- 				if (val > 0)
- 					sc->sc_ctstimeconf = val;
- 				else
- 					sc->sc_ctstimeconf = 0;
--				ath_settiming(sc);
-+				ath_set_timing(sc);
-+				break;
-+			case ATH_DISTANCE:
-+				if (val > 0) {
-+					sc->sc_coverage = ((val - 1) / 300) + 1;
-+					ic->ic_coverageclass = ((sc->sc_coverage - 1) / 3) + 1;
-+				} else {
-+					sc->sc_coverage = 0;
-+					ic->ic_coverageclass = 0;
-+				}
-+				ath_set_timing(sc);
- 				break;
- 			case ATH_SOFTLED:
- 				if (val != sc->sc_softled) {
-@@ -11338,6 +11388,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 		case ATH_CHANBW:
- 			val = sc->sc_chanbw ?: 20;
- 			break;
-+		case ATH_DISTANCE:
-+			val = sc->sc_coverage * 300;
-+			break;
- 		case ATH_SLOTTIME:
- 			val = ath_hal_getslottime(ah);
- 			break;
-@@ -11459,6 +11512,12 @@ static const ctl_table ath_sysctl_templa
- 	  .extra2	= (void *)ATH_CTSTIMEOUT,
- 	},
- 	{ .ctl_name	= CTL_AUTO,
-+	  .procname	= "distance",
-+	  .mode		= 0644,
-+	  .proc_handler	= ath_sysctl_halparam,
-+	  .extra2	= (void *)ATH_DISTANCE,
-+	},
-+	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "softled",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
---- a/ath/if_ath_hal.h
-+++ b/ath/if_ath_hal.h
-@@ -284,6 +284,17 @@ static inline u_int ath_hal_getslottime(
- 	return ret;
- }
- 
-+static inline u_int ath_hal_geteifstime(struct ath_hal *ah)
-+{
-+	u_int ret;
-+	ATH_HAL_LOCK_IRQ(ah->ah_sc);
-+	ath_hal_set_function(__func__);
-+	ret = ah->ah_getEifsTime(ah);
-+	ath_hal_set_function(NULL);
-+	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
-+	return ret;
-+}
-+
- static inline void ath_hal_beaconinit(struct ath_hal *ah, u_int32_t nexttbtt,
- 				      u_int32_t intval)
- {
-@@ -839,6 +850,17 @@ static inline HAL_BOOL ath_hal_setslotti
- 	ath_hal_set_function(NULL);
- 	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
- 	return ret;
-+}
-+
-+static inline HAL_BOOL ath_hal_seteifstime(struct ath_hal *ah, u_int a1)
-+{
-+	HAL_BOOL ret;
-+	ATH_HAL_LOCK_IRQ(ah->ah_sc);
-+	ath_hal_set_function(__func__);
-+	ret = ah->ah_setEifsTime(ah, a1);
-+	ath_hal_set_function(NULL);
-+	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
-+	return ret;
- }
- 
- static inline void ath_hal_setledstate(struct ath_hal *ah, HAL_LED_STATE a1)
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -613,6 +613,15 @@ struct ath_rp {
- 	int       rp_analyzed;
- };
- 
-+struct ath_timings {
-+	u_int	slot;
-+	u_int	ack;
-+	u_int	cts;
-+	u_int	sifs;
-+	u_int	difs;
-+	u_int	eifs;
-+};
-+
- struct ath_softc {
- 	struct ieee80211com sc_ic;		/* NB: must be first */
- 	struct net_device *sc_dev;
-@@ -839,6 +848,8 @@ struct ath_softc {
- 						 * detected radars */
- 	u_int32_t sc_nexttbtt;
- 	u_int64_t sc_last_tsf;
-+	u_int sc_coverage;
-+	struct ath_timings sc_timings;
- };
- 
- typedef void (*ath_callback) (struct ath_softc *);
-@@ -946,49 +957,76 @@ int ar_device(int devid);
- 	  DEV_NAME(_v->iv_ic->ic_dev))
- 
- void ath_radar_detected(struct ath_softc *sc, const char* message);
--static inline u_int getTimingOffset(struct ath_softc *sc)
--{
--	struct ieee80211com *ic = &sc->sc_ic;
--	u_int usec = 9;
--	if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
--		usec = 20;
--		if (ic->ic_flags & IEEE80211_F_SHSLOT)
--			usec = 9;
--	} else if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
--		usec = 9;
--
--	if (IEEE80211_IS_CHAN_TURBO(ic->ic_curchan))
--		usec = 6;
--
--	if (IEEE80211_IS_CHAN_HALF(ic->ic_curchan))
--		usec = 13;
--	else if (IEEE80211_IS_CHAN_QUARTER(ic->ic_curchan))
--		usec = 21;
--	return usec;
--}
- 
--static inline void ath_get_timings(struct ath_softc *sc, u_int *t_slot, u_int *t_sifs, u_int *t_difs)
--{
--	struct ieee80211_channel *c = sc->sc_ic.ic_curchan;
-+#ifndef MIN
-+#define MIN(a,b)        ((a) < (b) ? (a) : (b))
-+#endif
-+#ifndef MAX
-+#define MAX(a,b)        ((a) > (b) ? (a) : (b))
-+#endif
- 
--	*t_slot = getTimingOffset(sc) + sc->sc_slottimeconf;
- 
--	if (IEEE80211_IS_CHAN_HALF(c)) {
--		*t_sifs = 32;
--		*t_difs = 56;
--	} else if (IEEE80211_IS_CHAN_QUARTER(c)) {
--		*t_sifs = 64;
--		*t_difs = 112;
--	} else if (IEEE80211_IS_CHAN_TURBO(c)) {
--		*t_sifs = 8;
--		*t_difs = 28;
--	} else {
--		*t_sifs = 16;
--		*t_difs = 28;
--	}
-+/* Calculate the transmit duration of a frame. */
-+static inline unsigned
-+calc_usecs_unicast_packet(struct ath_softc *sc, int length,
-+		int rix, int short_retries, int long_retries)
-+{
-+		const HAL_RATE_TABLE *rt = sc->sc_currates;
-+		struct ieee80211com *ic = &sc->sc_ic;
-+		struct ath_timings *t = &sc->sc_timings;
-+		unsigned int x = 0, tt = 0;
-+		unsigned int cix = rt->info[rix].controlRate;
-+		int rts = 0, cts = 0;
-+		int cw = ATH_DEFAULT_CWMIN;
-+
-+		KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
-+
-+		if (!rt->info[rix].rateKbps) {
-+			printk(KERN_WARNING "rix %d (%d) bad ratekbps %d mode %u\n",
-+			       rix, rt->info[rix].dot11Rate,
-+			       rt->info[rix].rateKbps,
-+			       sc->sc_curmode);
-+			return 0;
-+		}
-+
-+		if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
-+			(rt->info[rix].phy == IEEE80211_T_OFDM)) {
-+
-+			if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
-+				rts = 1;
-+			else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
-+				cts = 1;
-+
-+			cix = rt->info[sc->sc_protrix].controlRate;
-+		}
-+
-+		if ((rts || cts) && rt->info[cix].rateKbps) {
-+			int ctsrate = rt->info[cix].rateCode;
-+			int ctsduration = 0;
-+
-+			ctsrate |= rt->info[cix].shortPreamble;
-+			if (rts)	/* SIFS + CTS */
-+				ctsduration += rt->info[cix].spAckDuration;
-+
-+			ctsduration += ath_hal_computetxtime(sc->sc_ah,
-+							     rt, length, rix, AH_TRUE);
-+
-+			if (cts)	/* SIFS + ACK */
-+				ctsduration += rt->info[cix].spAckDuration;
-+
-+			tt += (short_retries + 1) * ctsduration;
-+		}
-+		tt += t->difs;
-+		tt += (long_retries + 1) * (t->sifs + rt->info[rix].spAckDuration);
-+		tt += (long_retries + 1) * ath_hal_computetxtime(sc->sc_ah, rt, length,
-+							rix, AH_TRUE);
-+		for (x = 0; x <= short_retries + long_retries; x++) {
-+			cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2);
-+			tt += (t->slot * cw / 2);
-+		}
-+		return tt;
- }
- 
--
- struct ath_hw_detect {
- 	const char *vendor_name;
- 	const char *card_name;
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -170,85 +170,6 @@ rate_to_ndx(struct minstrel_node *sn, in
- 		return -1;
- }
- 
--/* Calculate the transmit duration of a frame. */
--static unsigned
--calc_usecs_unicast_packet(struct ath_softc *sc, int length,
--		int rix, int short_retries, int long_retries)
--{
--		const HAL_RATE_TABLE *rt = sc->sc_currates;
--		struct ieee80211com *ic = &sc->sc_ic;
--		unsigned t_slot = 20;
--		unsigned t_difs = 50;
--		unsigned t_sifs = 10;
--		unsigned int x = 0, tt = 0;
--		unsigned int cix = rt->info[rix].controlRate;
--		int rts = 0, cts = 0;
--		int cw = ATH_DEFAULT_CWMIN;
--
--		KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
--
--		if (!rt->info[rix].rateKbps) {
--			printk(KERN_WARNING "rix %d (%d) bad ratekbps %d mode %u\n",
--			       rix, rt->info[rix].dot11Rate,
--			       rt->info[rix].rateKbps,
--			       sc->sc_curmode);
--			return 0;
--		}
--
--		ath_get_timings(sc, &t_slot, &t_sifs, &t_difs);
--		if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
--		(rt->info[rix].phy == IEEE80211_T_OFDM)) {
--			if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
--				rts = 1;
--			else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
--				cts = 1;
--
--			cix = rt->info[sc->sc_protrix].controlRate;
--		}
--
--#if 0
--		if (length > ic->ic_rtsthreshold)
--			rts = 1;
--#endif
--
--		if (rts || cts) {
--			int ctsrate = rt->info[cix].rateCode;
--			int ctsduration = 0;
--
--			if (!rt->info[cix].rateKbps) {
--#if 0
--				printk(KERN_WARNING "cix %d (%d) bad ratekbps %d mode %u\n",
--				       cix, rt->info[cix].dot11Rate,
--				       rt->info[cix].rateKbps,
--				       sc->sc_curmode);
--#endif
--				return 0;
--			}
--
--
--			ctsrate |= rt->info[cix].shortPreamble;
--			if (rts)	/* SIFS + CTS */
--				ctsduration += rt->info[cix].spAckDuration;
--
--			ctsduration += ath_hal_computetxtime(sc->sc_ah,
--							     rt, length, rix, AH_TRUE);
--
--			if (cts)	/* SIFS + ACK */
--				ctsduration += rt->info[cix].spAckDuration;
--
--			tt += (short_retries + 1) * ctsduration;
--		}
--		tt += t_difs;
--		tt += (long_retries + 1) * (t_sifs + rt->info[rix].spAckDuration);
--		tt += (long_retries + 1) * ath_hal_computetxtime(sc->sc_ah, rt, length,
--							rix, AH_TRUE);
--		for (x = 0; x <= short_retries + long_retries; x++) {
--			cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2);
--			tt += (t_slot * cw / 2);
--		}
--		return tt;
--}
--
- static void
- ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
- {
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -137,92 +137,6 @@ rate_to_ndx(struct sample_node *sn, int
- 	return -1;
- }
- 
--/*
-- * Calculate the transmit duration of a frame.
-- */
--static unsigned
--calc_usecs_unicast_packet(struct ath_softc *sc, int length,
--	int rix, int short_retries, int long_retries)
--{
--	const HAL_RATE_TABLE *rt = sc->sc_currates;
--	int rts, cts;
--
--	unsigned t_slot;
--	unsigned t_difs;
--	unsigned t_sifs;
--	struct ieee80211com *ic = &sc->sc_ic;
--	unsigned int tt = 0;
--	unsigned int x;
--	unsigned int cw = ATH_DEFAULT_CWMIN;
--	unsigned int cix = rt->info[rix].controlRate;
--	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
--
--	if (!rt->info[rix].rateKbps) {
--		printk(KERN_WARNING "rix %u (%u) bad ratekbps %u mode %u\n",
--		       rix, rt->info[rix].dot11Rate,
--		       rt->info[rix].rateKbps,
--		       sc->sc_curmode);
--
--		return 0;
--	}
--
--	cix = rt->info[rix].controlRate;
--	/* 
--	 * XXX getting mac/phy level timings should be fixed for turbo
--	 * rates, and there is probably a way to get this from the
--	 * hal...
--	 */
--	ath_get_timings(sc, &t_slot, &t_sifs, &t_difs);
--	rts = cts = 0;
--
--	if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
--	    rt->info[rix].phy == IEEE80211_T_OFDM) {
--		if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
--			rts = 1;
--		else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
--			cts = 1;
--
--		cix = rt->info[sc->sc_protrix].controlRate;
--	}
--
--	if (0 /*length > ic->ic_rtsthreshold */)
--		rts = 1;
--
--	if (rts || cts) {
--		int ctsrate;
--		int ctsduration = 0;
--
--		if (!rt->info[cix].rateKbps) {
--			printk(KERN_WARNING "cix %u (%u) bad ratekbps %u mode %u\n",
--			       cix, rt->info[cix].dot11Rate,
--			       rt->info[cix].rateKbps,
--			       sc->sc_curmode);
--			return 0;
--		}
--
--
--		ctsrate = rt->info[cix].rateCode | rt->info[cix].shortPreamble;
--		if (rts)		/* SIFS + CTS */
--			ctsduration += rt->info[cix].spAckDuration;
--
--		ctsduration += ath_hal_computetxtime(sc->sc_ah,
--						     rt, length, rix, AH_TRUE);
--
--		if (cts)	/* SIFS + ACK */
--			ctsduration += rt->info[cix].spAckDuration;
--
--		tt += (short_retries + 1) * ctsduration;
--	}
--	tt += t_difs;
--	tt += (long_retries+1)*(t_sifs + rt->info[rix].spAckDuration);
--	tt += (long_retries+1)*ath_hal_computetxtime(sc->sc_ah, rt, length,
--						rix, AH_TRUE);
--	for (x = 0; x <= short_retries + long_retries; x++) {
--		cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2);
--		tt += (t_slot * cw / 2);
--	}
--	return tt;
--}
- 
- static void
- ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2745,6 +2745,7 @@ ieee80211_ioctl_setparam(struct net_devi
- 	case IEEE80211_PARAM_COVERAGE_CLASS:
- 		if (value <= IEEE80211_COVERAGE_CLASS_MAX) {
- 			ic->ic_coverageclass = value;
-+			ic->ic_set_coverageclass(ic);
- 			if (IS_UP_AUTO(vap))
- 				ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
- 			retv = 0;
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -94,7 +94,7 @@
- 
- #define IEEE80211_BGSCAN_TRIGGER_INTVL 20 /* min trigger interval for thresh based bgscan (secs) */
- 
--#define IEEE80211_COVERAGE_CLASS_MAX	31	/* max coverage class */
-+#define IEEE80211_COVERAGE_CLASS_MAX	255	/* max coverage class */
- #define IEEE80211_REGCLASSIDS_MAX	10	/* max regclass id list */
- 
- #define	IEEE80211_PS_SLEEP	0x1		/* STA is in power saving mode */
---- a/tools/Makefile
-+++ b/tools/Makefile
-@@ -50,7 +50,7 @@ all: compile
- 
- DEBUG = -DAR_DEBUG
- 
--ALLPROGS=	athstats 80211stats athkey athchans athctrl \
-+ALLPROGS=	athstats 80211stats athkey athchans \
- 	$(if $(DEBUG),athdebug 80211debug) wlanconfig ath_info
- 
- OBJS=	$(patsubst %,%.o,$(ALLPROGS))
---- a/tools/athctrl.c
-+++ /dev/null
-@@ -1,133 +0,0 @@
--/*-
-- * Copyright (c) 2002-2004 Gunter Burchardt, Local-Web AG
-- * All rights reserved.
-- *
-- * Redistribution and use in source and binary forms, with or without
-- * modification, are permitted provided that the following conditions
-- * are met:
-- * 1. Redistributions of source code must retain the above copyright
-- *    notice, this list of conditions and the following disclaimer,
-- *    without modification.
-- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
-- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
-- *    redistribution must be conditioned upon including a substantially
-- *    similar Disclaimer requirement for further binary redistribution.
-- * 3. Neither the names of the above-listed copyright holders nor the names
-- *    of any contributors may be used to endorse or promote products derived
-- *    from this software without specific prior written permission.
-- *
-- * Alternatively, this software may be distributed under the terms of the
-- * GNU General Public License ("GPL") version 2 as published by the Free
-- * Software Foundation.
-- *
-- * NO WARRANTY
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
-- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
-- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-- * THE POSSIBILITY OF SUCH DAMAGES.
-- *
-- * $Id: athctrl.c 2394 2007-05-30 01:41:18Z mtaylor $
-- */
--
--/*
-- * Simple Atheros-specific tool to inspect and set atheros specific values
-- * athctrl [-i interface] [-d distance]
-- * (default interface is wifi0).  
-- */
--#include <sys/types.h>
--#include <sys/file.h>
--
--#include <getopt.h>
--
--#include <stdio.h>
--#include <string.h>
--#include <stdlib.h>
--#include <err.h>
--
--#include <net/if.h>
--#include "do_multi.h"
--
--static int
--setsysctrl(const char *dev, const char *control , u_long value)
--{
--	char buffer[256];
--	FILE * fd;
--
--	snprintf(buffer, sizeof(buffer), "/proc/sys/dev/%s/%s", dev, control);
--	fd = fopen(buffer, "w");
--	if (fd != NULL) {
--		fprintf(fd, "%li", value);
--		fclose(fd);
--	} else
--		fprintf(stderr, "Could not open %s for writing!\n", buffer);
--
--	return 0;
--}
--
--static void usage(void)
--{
--	fprintf(stderr,
--	    "Atheros driver control\n"
--	    "Copyright (c) 2002-2004 Gunter Burchardt, Local-Web AG\n"
--	    "\n"
--	    "usage: athctrl [-i interface] [-d distance]\n"
--	    "\n"
--	    "options:\n"
--	    "   -h   show this usage\n"
--	"   -i   interface (default interface is wifi0)\n"
--	    "   -d   specify the maximum distance of a sta or the distance\n"
--	"        of the master\n");
--
--	exit(1);
--}
--
--int
--CMD(athctrl)(int argc, char *argv[])
--{
--	char device[IFNAMSIZ + 1];
--	int distance = -1;
--	int c;
--
--	strncpy(device, "wifi0", sizeof (device));
--
--	for (;;) {
--	    	c = getopt(argc, argv, "d:i:h");
--	    	if (c < 0)
--			break;
--	    	switch (c) {
--	    	case 'h':
--			usage();
--			break;
--	    	case 'd':
--			distance = atoi(optarg);
--			break;
--	    	case 'i':
--			strncpy(device, optarg, sizeof (device));
--			break;
--	    	default:
--			usage();
--			break;
--	    	}
--	}
--
--	if (distance >= 0) {
--		int slottime = (distance / 300) + ((distance % 300) ? 1 : 0);
--		int acktimeout = slottime * 2 + 3;
--		int ctstimeout = slottime * 2 + 3;
--
--		printf("Setting distance on interface %s to %i meters\n",
--			device, distance);
--		setsysctrl(device, "slottime", slottime);
--		setsysctrl(device, "acktimeout", acktimeout);
--		setsysctrl(device, "ctstimeout", ctstimeout);
--	} else
--		usage();
--	return 0;
--}
---- a/tools/do_multi.c
-+++ b/tools/do_multi.c
-@@ -18,8 +18,6 @@ main(int argc, char *argv[])
- 	ret = a80211stats_init(argc, argv);
-     if(strcmp(progname, "athchans") == 0)
- 	ret = athchans_init(argc, argv);
--    if(strcmp(progname, "athctrl") == 0)
--	ret =  athctrl_init(argc, argv);
- #ifdef AR_DEBUG
-     if(strcmp(progname, "athdebug") == 0)
- 	ret =  athdebug_init(argc, argv);
---- a/tools/do_multi.h
-+++ b/tools/do_multi.h
-@@ -2,7 +2,6 @@
- int a80211debug_init(int argc, char *argv[]);
- int a80211stats_init(int argc, char *argv[]);
- int athchans_init(int argc, char *argv[]);
--int athctrl_init(int argc, char *argv[]);
- int athdebug_init(int argc, char *argv[]);
- int athkey_init(int argc, char *argv[]);
- int athstats_init(int argc, char *argv[]);
---- a/ath_rate/minstrel/minstrel.h
-+++ b/ath_rate/minstrel/minstrel.h
-@@ -172,14 +172,6 @@ struct minstrel_node {
- 
- #define	ATH_NODE_MINSTREL(an)	((struct minstrel_node *)&an[1])
- 
--
--#ifndef MIN
--#define MIN(a,b)        ((a) < (b) ? (a) : (b))
--#endif
--#ifndef MAX
--#define MAX(a,b)        ((a) > (b) ? (a) : (b))
--#endif
--
- /*
-  * Definitions for pulling the rate and trie counts from
-  * a 5212 h/w descriptor. These Don't belong here; the
---- a/ath_rate/sample/sample.h
-+++ b/ath_rate/sample/sample.h
-@@ -98,14 +98,6 @@ struct sample_node {
- };
- #define	ATH_NODE_SAMPLE(an)	((struct sample_node *)&an[1])
- 
--
--#ifndef MIN
--#define MIN(a,b)        ((a) < (b) ? (a) : (b))
--#endif
--#ifndef MAX
--#define MAX(a,b)        ((a) > (b) ? (a) : (b))
--#endif
--
- /*
-  * Definitions for pulling the rate and trie counts from
-  * a 5212 h/w descriptor. These Don't belong here; the
diff --git a/package/madwifi/patches/425-rc_rexmit.patch b/package/madwifi/patches/425-rc_rexmit.patch
deleted file mode 100644
index 252767a8cf..0000000000
--- a/package/madwifi/patches/425-rc_rexmit.patch
+++ /dev/null
@@ -1,506 +0,0 @@
---- a/net80211/ieee80211_rate.h
-+++ b/net80211/ieee80211_rate.h
-@@ -81,6 +81,8 @@ struct ieee80211vap;
- 
- /* Multi-rare retry: 3 additional rate/retry pairs */
- struct ieee80211_mrr {
-+	int rate0;
-+	int retries0;
- 	int rate1;
- 	int retries1;
- 	int rate2;
-@@ -142,7 +144,7 @@ struct ieee80211_rate_ops {
- 	 * for packets that were successfully sent and for those that
- 	 * failed (consult the descriptor for details). */
- 	void (*tx_complete)(struct ath_softc *sc, struct ath_node *an,
--			    const struct ath_buf *bf);
-+			    const struct ath_buf *bf, const struct ieee80211_mrr *mrr);
- };
- 
- struct ath_ratectrl {
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -8638,6 +8638,8 @@ ath_tx_processq(struct ath_softc *sc, st
- 
- 		ni = bf->bf_node;
- 		if (ni != NULL) {
-+			struct ieee80211_mrr mrr;
-+
- 			an = ATH_NODE(ni);
- 			if (ts->ts_status == 0) {
- 				u_int8_t txant = ts->ts_antenna;
-@@ -8690,15 +8692,43 @@ ath_tx_processq(struct ath_softc *sc, st
- 			lr = ts->ts_longretry;
- 			sc->sc_stats.ast_tx_shortretry += sr;
- 			sc->sc_stats.ast_tx_longretry += lr;
-+			memset(&mrr, 0, sizeof(mrr));
-+
-+			switch(ah->ah_macType) {
-+			case 5210:
-+			case 5211:
-+				goto skip_mrr;
-+
-+			case 5212:
-+				mrr.rate0 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate0)].ieeerate;
-+				mrr.rate1 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate1)].ieeerate;
-+				mrr.rate2 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate2)].ieeerate;
-+				mrr.rate3 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate3)].ieeerate;
-+				break;
-+
-+			case 5416:
-+				mrr.rate0 = sc->sc_hwmap[MS(ds->ds_ctl3, AR5416_XmitRate0)].ieeerate;
-+				mrr.rate1 = sc->sc_hwmap[MS(ds->ds_ctl3, AR5416_XmitRate1)].ieeerate;
-+				mrr.rate2 = sc->sc_hwmap[MS(ds->ds_ctl3, AR5416_XmitRate2)].ieeerate;
-+				mrr.rate3 = sc->sc_hwmap[MS(ds->ds_ctl3, AR5416_XmitRate3)].ieeerate;
-+				break;
-+			}
-+
-+			mrr.retries0 = MS(ds->ds_ctl2, AR_XmitDataTries0);
-+			mrr.retries1 = MS(ds->ds_ctl2, AR_XmitDataTries1);
-+			mrr.retries2 = MS(ds->ds_ctl2, AR_XmitDataTries2);
-+			mrr.retries3 = MS(ds->ds_ctl2, AR_XmitDataTries3);
-+
- 			/*
- 			 * Hand the descriptor to the rate control algorithm
- 			 * if the frame wasn't dropped for filtering or sent
- 			 * w/o waiting for an ack.  In those cases the rssi
- 			 * and retry counts will be meaningless.
- 			 */
-+skip_mrr:
- 			if ((ts->ts_status & HAL_TXERR_FILT) == 0 &&
- 			    (bf->bf_flags & HAL_TXDESC_NOACK) == 0)
--				sc->sc_rc->ops->tx_complete(sc, an, bf);
-+				sc->sc_rc->ops->tx_complete(sc, an, bf, &mrr);
- 		}
- 
- 		bus_unmap_single(sc->sc_bdev, bf->bf_skbaddr,
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -595,6 +595,46 @@ struct ath_vap {
- 	(_tqs)->axq_link = NULL; \
- } while (0)
- 
-+/*
-+ * Definitions for pulling the rate and trie counts from
-+ * a 5212 h/w descriptor. These Don't belong here; the
-+ * driver should record this information so the rate control
-+ * code doesn't go groveling around in the descriptor bits.
-+ */
-+#define	ds_ctl2	ds_hw[0]
-+#define	ds_ctl3	ds_hw[1]
-+
-+/* TX ds_ctl3 */
-+#define	AR_XmitDataTries0	0x000f0000	/* series 0 max attempts */
-+#define	AR_XmitDataTries0_S	16
-+#define	AR_XmitDataTries1	0x00f00000	/* series 1 max attempts */
-+#define	AR_XmitDataTries1_S	20
-+#define	AR_XmitDataTries2	0x0f000000	/* series 2 max attempts */
-+#define	AR_XmitDataTries2_S	24
-+#define	AR_XmitDataTries3	0xf0000000	/* series 3 max attempts */
-+#define	AR_XmitDataTries3_S	28
-+
-+/* TX ds_ctl3 */
-+#define	AR_XmitRate0		0x0000001f	/* series 0 tx rate */
-+#define	AR_XmitRate0_S		0
-+#define	AR_XmitRate1		0x000003e0	/* series 1 tx rate */
-+#define	AR_XmitRate1_S		5
-+#define	AR_XmitRate2		0x00007c00	/* series 2 tx rate */
-+#define	AR_XmitRate2_S		10
-+#define	AR_XmitRate3		0x000f8000	/* series 3 tx rate */
-+#define	AR_XmitRate3_S		15
-+
-+#define AR5416_XmitRate0        0x000000ff
-+#define AR5416_XmitRate0_S      0
-+#define AR5416_XmitRate1        0x0000ff00
-+#define AR5416_XmitRate1_S      8
-+#define AR5416_XmitRate2        0x00ff0000
-+#define AR5416_XmitRate2_S      16
-+#define AR5416_XmitRate3        0xff000000
-+#define AR5416_XmitRate3_S      24
-+
-+#define MS(_v, _f)	(((_v) & (_f)) >> _f##_S)
-+
- /* 
-  * concat buffers from one queue to other
-  */
---- a/ath_rate/amrr/amrr.c
-+++ b/ath_rate/amrr/amrr.c
-@@ -123,7 +123,8 @@ ath_rate_get_mrr(struct ath_softc *sc, s
- 
- static void
- ath_rate_tx_complete(struct ath_softc *sc,
--	struct ath_node *an, const struct ath_buf *bf)
-+	struct ath_node *an, const struct ath_buf *bf,
-+	const struct ieee80211_mrr *mrr)
- {
- 	struct amrr_node *amn = ATH_NODE_AMRR(an);
- 	const struct ath_tx_status *ts = &bf->bf_dsstatus.ds_txstat;
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -333,7 +333,8 @@ ath_rate_get_mrr(struct ath_softc *sc, s
- 
- static void
- ath_rate_tx_complete(struct ath_softc *sc,
--		struct ath_node *an, const struct ath_buf *bf)
-+		struct ath_node *an, const struct ath_buf *bf,
-+		const struct ieee80211_mrr *mrr)
- {
- 		struct minstrel_node *sn = ATH_NODE_MINSTREL(an);
- 		struct ieee80211com *ic = &sc->sc_ic;
-@@ -341,12 +342,9 @@ ath_rate_tx_complete(struct ath_softc *s
- 		const struct ath_desc *ds = &bf->bf_desc[0];
- 		int final_rate = 0;
- 		int tries = 0;
--		int mrr;
-+		int use_mrr;
- 		int final_ndx;
--		int rate0, tries0, ndx0;
--		int rate1, tries1, ndx1;
--		int rate2, tries2, ndx2;
--		int rate3, tries3, ndx3;
-+		int ndx0, ndx1, ndx2, ndx3;
- 
- 		/* This is the index in the retry chain we finish at.
- 		 * With no retransmits, it is always 0.
-@@ -376,9 +374,9 @@ ath_rate_tx_complete(struct ath_softc *s
- 		if (!ts->ts_status)  /* Success when sending a packet*/
- 			sn->rs_ratesuccess[final_ndx]++;
- 
--		mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) && ENABLE_MRR;
-+		use_mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) && ENABLE_MRR;
- 
--		if (!mrr) {
-+		if (!use_mrr) {
- 			if ((0 <= final_ndx) && (final_ndx < sn->num_rates)) {
- 				sn->rs_rateattempts[final_ndx] += tries; /* only one rate was used */
- 			}
-@@ -388,47 +386,36 @@ ath_rate_tx_complete(struct ath_softc *s
- 		/* Now, query the hal/hardware to find out the contents of the multirate retry chain.
- 		 * If we have it set to 6,3,2,2, this call will always return 6,3,2,2. For some packets, we can
- 		 * get a mrr of 0, -1, -1, -1, which indicates there is no chain installed for that packet */
--		rate0 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate0)].ieeerate;
--		tries0 = MS(ds->ds_ctl2, AR_XmitDataTries0);
--		ndx0 = rate_to_ndx(sn, rate0);
-+		ndx0 = rate_to_ndx(sn, mrr->rate0);
-+		ndx1 = rate_to_ndx(sn, mrr->rate1);
-+		ndx2 = rate_to_ndx(sn, mrr->rate2);
-+		ndx3 = rate_to_ndx(sn, mrr->rate3);
- 
--		rate1 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate1)].ieeerate;
--		tries1 = MS(ds->ds_ctl2, AR_XmitDataTries1);
--		ndx1 = rate_to_ndx(sn, rate1);
--
--		rate2 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate2)].ieeerate;
--		tries2 = MS(ds->ds_ctl2, AR_XmitDataTries2);
--		ndx2 = rate_to_ndx(sn, rate2);
--
--		rate3 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate3)].ieeerate;
--		tries3 = MS(ds->ds_ctl2, AR_XmitDataTries3);
--		ndx3 = rate_to_ndx(sn, rate3);
--
--		sn->rs_rateattempts[ndx0] += MIN(tries, tries0);
--		if (tries <= tries0)
-+		sn->rs_rateattempts[ndx0] += MIN(tries, mrr->retries0);
-+		if (tries <= mrr->retries0)
- 			return;
- 
--		if (tries1 < 0)
-+		if (mrr->retries1 < 0)
- 			return;
--		tries = tries - tries0;
--		sn->rs_rateattempts[ndx1] += MIN(tries, tries1);
--		if (tries <= tries1)
-+		tries = tries - mrr->retries0;
-+		sn->rs_rateattempts[ndx1] += MIN(tries, mrr->retries1);
-+		if (tries <= mrr->retries1)
- 			return;
- 
- 		if (bf->rcflags)
- 			sn->sample_count++;
- 
--		if  (tries2 < 0)
-+		if (mrr->retries2 < 0)
- 			return;
--		tries = tries - tries1;
--		sn->rs_rateattempts[ndx2] += MIN(tries, tries2);
--		if (tries <= tries2)
-+		tries = tries - mrr->retries1;
-+		sn->rs_rateattempts[ndx2] += MIN(tries, mrr->retries2);
-+		if (tries <= mrr->retries2)
- 			return;
- 
--		if  (tries3 < 0)
-+		if (mrr->retries3 < 0)
- 			return;
--		tries = tries - tries2;
--		sn->rs_rateattempts[ndx3] += MIN(tries, tries3);
-+		tries = tries - mrr->retries2;
-+		sn->rs_rateattempts[ndx3] += MIN(tries, mrr->retries3);
- }
- 
- static void
---- a/ath_rate/minstrel/minstrel.h
-+++ b/ath_rate/minstrel/minstrel.h
-@@ -172,36 +172,6 @@ struct minstrel_node {
- 
- #define	ATH_NODE_MINSTREL(an)	((struct minstrel_node *)&an[1])
- 
--/*
-- * Definitions for pulling the rate and trie counts from
-- * a 5212 h/w descriptor. These Don't belong here; the
-- * driver should record this information so the rate control
-- * code doesn't go groveling around in the descriptor bits.
-- */
--#define	ds_ctl2	ds_hw[0]
--#define	ds_ctl3	ds_hw[1]
--
--/* TX ds_ctl3 */
--#define	AR_XmitDataTries0	0x000f0000	/* series 0 max attempts */
--#define	AR_XmitDataTries0_S	16
--#define	AR_XmitDataTries1	0x00f00000	/* series 1 max attempts */
--#define	AR_XmitDataTries1_S	20
--#define	AR_XmitDataTries2	0x0f000000	/* series 2 max attempts */
--#define	AR_XmitDataTries2_S	24
--#define	AR_XmitDataTries3	0xf0000000	/* series 3 max attempts */
--#define	AR_XmitDataTries3_S	28
--
--/* TX ds_ctl3 */
--#define	AR_XmitRate0		0x0000001f	/* series 0 tx rate */
--#define	AR_XmitRate0_S		0
--#define	AR_XmitRate1		0x000003e0	/* series 1 tx rate */
--#define	AR_XmitRate1_S		5
--#define	AR_XmitRate2		0x00007c00	/* series 2 tx rate */
--#define	AR_XmitRate2_S		10
--#define	AR_XmitRate3		0x000f8000	/* series 3 tx rate */
--#define	AR_XmitRate3_S		15
--
--#define MS(_v, _f)	(((_v) & (_f)) >> _f##_S)
- #endif /* _DEV_ATH_RATE_MINSTEL_H */
- 
- /* The comment below is magic for those who use emacs to edit this file. */
---- a/ath_rate/onoe/onoe.c
-+++ b/ath_rate/onoe/onoe.c
-@@ -137,7 +137,8 @@ ath_rate_get_mrr(struct ath_softc *sc, s
- 
- static void
- ath_rate_tx_complete(struct ath_softc *sc,
--	struct ath_node *an, const struct ath_buf *bf)
-+	struct ath_node *an, const struct ath_buf *bf,
-+	const struct ieee80211_mrr *mrr)
- {
- 	struct onoe_node *on = ATH_NODE_ONOE(an);
- 	const struct ath_tx_status *ts = &bf->bf_dsstatus.ds_txstat;
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -178,10 +178,6 @@ static __inline int best_rate_ndx(struct
- 		    !sn->stats[size_bin][x].packets_acked))
- 			continue;
- 
--		/* 9 megabits never works better than 12 */
--		if (sn->rates[x].rate == 18)
--			continue;
--
- 		/* don't use a bit-rate that has been failing */
- 		if (sn->stats[size_bin][x].successive_failures > 3)
- 			continue;
-@@ -234,10 +230,6 @@ pick_sample_ndx(struct sample_node *sn,
- 		if (sn->rates[ndx].rate > 22 && ndx > current_ndx + 2)
- 			continue;
- 
--		/* 9 megabits never works better than 12 */
--		if (sn->rates[ndx].rate == 18)
--			continue;
--
- 		/* if we're using 11 megabits, only sample up to 12 megabits
- 		 */
- 		if (sn->rates[current_ndx].rate == 22 && ndx > current_ndx + 1)
-@@ -531,7 +523,8 @@ update_stats(struct ath_softc *sc, struc
- 
- static void
- ath_rate_tx_complete(struct ath_softc *sc,
--	struct ath_node *an, const struct ath_buf *bf)
-+	struct ath_node *an, const struct ath_buf *bf,
-+	const struct ieee80211_mrr *mrr)
- {
- 	struct sample_node *sn = ATH_NODE_SAMPLE(an);
- 	struct ieee80211com *ic = &sc->sc_ic;
-@@ -541,7 +534,7 @@ ath_rate_tx_complete(struct ath_softc *s
- 	unsigned int short_tries;
- 	unsigned int long_tries;
- 	unsigned int frame_size;
--	unsigned int mrr;
-+	unsigned int use_mrr;
- 
- 	final_rate = sc->sc_hwmap[ts->ts_rate &~ HAL_TXSTAT_ALTRATE].ieeerate;
- 	short_tries = ts->ts_shortretry + 1;
-@@ -557,7 +550,7 @@ ath_rate_tx_complete(struct ath_softc *s
- 		return;
- 	}
- 
--	mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) && ENABLE_MRR;
-+	use_mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) && ENABLE_MRR;
- 
- 
- 	if (sc->sc_mrretry && ts->ts_status) {
-@@ -566,22 +559,15 @@ ath_rate_tx_complete(struct ath_softc *s
- 			dev_info,
- 			MAC_ADDR(an->an_node.ni_macaddr),
- 			bin_to_size(size_to_bin(frame_size)),
--			sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate0)].ieeerate,
--				MS(ds->ds_ctl2, AR_XmitDataTries0),
--			sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate1)].ieeerate,
--				MS(ds->ds_ctl2, AR_XmitDataTries1),
--			sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate2)].ieeerate,
--				MS(ds->ds_ctl2, AR_XmitDataTries2),
--			sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate3)].ieeerate,
--				MS(ds->ds_ctl2, AR_XmitDataTries3),
-+			mrr->rate0,
-+			mrr->rate1,
-+			mrr->rate2,
-+			mrr->rate3,
- 			ts->ts_status ? "FAIL" : "OK",
- 			short_tries, long_tries);
- 	}
- 
--	mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) && ENABLE_MRR;
--
--
--	if (!mrr || !(ts->ts_rate & HAL_TXSTAT_ALTRATE)) {
-+	if (!use_mrr || !(ts->ts_rate & HAL_TXSTAT_ALTRATE)) {
- 		/* only one rate was used */
- 		int ndx = rate_to_ndx(sn, final_rate);
- 		if ((ndx >= 0) && (ndx < sn->num_rates)) {
-@@ -593,7 +579,6 @@ ath_rate_tx_complete(struct ath_softc *s
- 				short_tries, long_tries, ts->ts_status);
- 		}
- 	} else {
--		unsigned int rate[4], tries[4];
- 		int ndx[4];
- 		int finalTSIdx = ts->ts_finaltsi;
- 
-@@ -601,21 +586,10 @@ ath_rate_tx_complete(struct ath_softc *s
- 		 * Process intermediate rates that failed.
- 		 */
- 
--		rate[0] = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate0)].ieeerate;
--		tries[0] = MS(ds->ds_ctl2, AR_XmitDataTries0);
--		ndx[0] = rate_to_ndx(sn, rate[0]);
--
--		rate[1] = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate1)].ieeerate;
--		tries[1] = MS(ds->ds_ctl2, AR_XmitDataTries1);
--		ndx[1] = rate_to_ndx(sn, rate[1]);
--
--		rate[2] = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate2)].ieeerate;
--		tries[2] = MS(ds->ds_ctl2, AR_XmitDataTries2);
--		ndx[2] = rate_to_ndx(sn, rate[2]);
--
--		rate[3] = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate3)].ieeerate;
--		tries[3] = MS(ds->ds_ctl2, AR_XmitDataTries3);
--		ndx[3] = rate_to_ndx(sn, rate[3]);
-+		ndx[0] = rate_to_ndx(sn, mrr->rate0);
-+		ndx[1] = rate_to_ndx(sn, mrr->rate1);
-+		ndx[2] = rate_to_ndx(sn, mrr->rate2);
-+		ndx[3] = rate_to_ndx(sn, mrr->rate3);
- 
- #if 0
- 		DPRINTF(sc, ATH_DEBUG_RATE, "%s: " MAC_FMT " size %u finaltsidx %u tries %u status %u rate/try %u/%u %u/%u %u/%u %u/%u\n",
-@@ -636,43 +610,43 @@ ath_rate_tx_complete(struct ath_softc *s
- 		 * sample higher rates 1 try at a time doing so
- 		 * may unfairly penalize them.
- 		 */
--		if (tries[0] && ndx[0] >= 0) {
-+		if (mrr->retries0 && ndx[0] >= 0) {
- 			update_stats(sc, an, frame_size,
--				ndx[0], tries[0],
--				ndx[1], tries[1],
--				ndx[2], tries[2],
--				ndx[3], tries[3],
-+				ndx[0], mrr->retries0,
-+				ndx[1], mrr->retries1,
-+				ndx[2], mrr->retries2,
-+				ndx[3], mrr->retries3,
- 				short_tries, long_tries,
--				long_tries > tries[0]);
--			long_tries -= tries[0];
-+				long_tries > mrr->retries0);
-+			long_tries -= mrr->retries0;
- 
- 		}
- 
--		if (tries[1] && ndx[1] >= 0 && finalTSIdx > 0) {
-+		if (mrr->retries1 && ndx[1] >= 0 && finalTSIdx > 0) {
- 			update_stats(sc, an, frame_size,
--				ndx[1], tries[1],
--				ndx[2], tries[2],
--				ndx[3], tries[3],
-+				ndx[1], mrr->retries1,
-+				ndx[2], mrr->retries2,
-+				ndx[3], mrr->retries3,
- 				0, 0,
- 				short_tries, long_tries,
- 				ts->ts_status);
--			long_tries -= tries[1];
-+			long_tries -= mrr->retries1;
- 		}
- 
--		if (tries[2] && ndx[2] >= 0 && finalTSIdx > 1) {
-+		if (mrr->retries2 && ndx[2] >= 0 && finalTSIdx > 1) {
- 			update_stats(sc, an, frame_size,
--				ndx[2], tries[2],
--				ndx[3], tries[3],
-+				ndx[2], mrr->retries2,
-+				ndx[3], mrr->retries3,
- 				0, 0,
- 				0, 0,
- 				short_tries, long_tries,
- 				ts->ts_status);
--			long_tries -= tries[2];
-+			long_tries -= mrr->retries2;
- 		}
- 
--		if (tries[3] && ndx[3] >= 0 && finalTSIdx > 2) {
-+		if (mrr->retries3 && ndx[3] >= 0 && finalTSIdx > 2) {
- 			update_stats(sc, an, frame_size,
--				ndx[3], tries[3],
-+				ndx[3], mrr->retries3,
- 				0, 0,
- 				0, 0,
- 				0, 0,
---- a/ath_rate/sample/sample.h
-+++ b/ath_rate/sample/sample.h
-@@ -98,35 +98,4 @@ struct sample_node {
- };
- #define	ATH_NODE_SAMPLE(an)	((struct sample_node *)&an[1])
- 
--/*
-- * Definitions for pulling the rate and trie counts from
-- * a 5212 h/w descriptor. These Don't belong here; the
-- * driver should record this information so the rate control
-- * code doesn't go groveling around in the descriptor bits.
-- */
--#define	ds_ctl2	ds_hw[0]
--#define	ds_ctl3	ds_hw[1]
--
--/* TX ds_ctl3 */
--#define	AR_XmitDataTries0	0x000f0000	/* series 0 max attempts */
--#define	AR_XmitDataTries0_S	16
--#define	AR_XmitDataTries1	0x00f00000	/* series 1 max attempts */
--#define	AR_XmitDataTries1_S	20
--#define	AR_XmitDataTries2	0x0f000000	/* series 2 max attempts */
--#define	AR_XmitDataTries2_S	24
--#define	AR_XmitDataTries3	0xf0000000	/* series 3 max attempts */
--#define	AR_XmitDataTries3_S	28
--
--/* TX ds_ctl3 */
--#define	AR_XmitRate0		0x0000001f	/* series 0 tx rate */
--#define	AR_XmitRate0_S		0
--#define	AR_XmitRate1		0x000003e0	/* series 1 tx rate */
--#define	AR_XmitRate1_S		5
--#define	AR_XmitRate2		0x00007c00	/* series 2 tx rate */
--#define	AR_XmitRate2_S		10
--#define	AR_XmitRate3		0x000f8000	/* series 3 tx rate */
--#define	AR_XmitRate3_S		15
--
--#define MS(_v, _f)	(((_v) & (_f)) >> _f##_S)
--
- #endif /* _DEV_ATH_RATE_SAMPLE_H */
diff --git a/package/madwifi/patches/426-header_len.patch b/package/madwifi/patches/426-header_len.patch
deleted file mode 100644
index acfbc18c65..0000000000
--- a/package/madwifi/patches/426-header_len.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -888,9 +888,6 @@ ath_attach(u_int16_t devid, struct net_d
- 				IEEE80211_ADDR_LEN +
- 				IEEE80211_WEP_IVLEN +
- 				IEEE80211_WEP_KIDLEN;
--#ifdef ATH_SUPERG_FF
--	dev->hard_header_len += ATH_FF_MAX_HDR;
--#endif
- #endif
- 	dev->type = ARPHRD_IEEE80211;
- 
diff --git a/package/madwifi/patches/427-ignore_eeprom_ff.patch b/package/madwifi/patches/427-ignore_eeprom_ff.patch
deleted file mode 100644
index eead70c992..0000000000
--- a/package/madwifi/patches/427-ignore_eeprom_ff.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -915,7 +915,7 @@ ath_attach(u_int16_t devid, struct net_d
- 	ic->ic_ath_cap = 0;
- 	sc->sc_fftxqmin = ATH_FF_TXQMIN;
- #ifdef ATH_SUPERG_FF
--	ic->ic_ath_cap |= (ath_hal_fastframesupported(ah) ? 
-+	ic->ic_ath_cap |= (ah->ah_macType >= 5212 ?
- 			IEEE80211_ATHC_FF : 0);
- #endif
- 	ic->ic_ath_cap |= (ath_hal_burstsupported(ah) ? 
diff --git a/package/madwifi/patches/430-use_netdev_priv.patch b/package/madwifi/patches/430-use_netdev_priv.patch
deleted file mode 100644
index 3f65424a5c..0000000000
--- a/package/madwifi/patches/430-use_netdev_priv.patch
+++ /dev/null
@@ -1,1936 +0,0 @@
---- a/ath/ath_wprobe.c
-+++ b/ath/ath_wprobe.c
-@@ -119,7 +119,7 @@ ath_wprobe_sync(struct wprobe_iface *dev
- 	struct ath_vap *avp = container_of(dev, struct ath_vap, av_wpif);
- 	struct ieee80211vap *vap = &avp->av_vap;
- 	struct ieee80211com *ic = vap->iv_ic;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	u32 cc, busy, rx, tx;
- 	s16 noise;
-@@ -192,7 +192,7 @@ ath_lookup_rateval(struct ieee80211_node
- {
- 	struct ieee80211vap *vap = ni->ni_vap;
- 	struct ieee80211com *ic = vap->iv_ic;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	const HAL_RATE_TABLE *rt = sc->sc_currates;
- 
- 	if ((!rt) || (rate < 0) || (rate >= ARRAY_SIZE(sc->sc_hwmap)))
---- a/ath/if_ath_ahb.c
-+++ b/ath/if_ath_ahb.c
-@@ -203,7 +203,7 @@ static int ahb_wmac_probe(struct platfor
- 	if (!dev)
- 		return -ENOMEM;
- 
--	sc = dev->priv;
-+	sc = netdev_priv(dev);
- 	sc->aps_sc.sc_dev = dev;
- 
- 	dev->irq = platform_get_irq(pdev, 0);
-@@ -300,7 +300,7 @@ init_ath_wmac(u_int16_t devid, u_int16_t
- 		printk(KERN_ERR "%s: no memory for device state\n", dev_info);
- 		goto bad2;
- 	}
--	sc = dev->priv;
-+	sc = netdev_priv(dev);
- 	sc->aps_sc.sc_dev = dev;
- 
- 	/*
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -569,7 +569,7 @@ static inline int rate_factor(int mode)
- int
- ath_attach(u_int16_t devid, struct net_device *dev, HAL_BUS_TAG tag)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ieee80211vap *vap;
- 	struct ath_hal *ah;
-@@ -1206,7 +1206,7 @@ bad:
- int
- ath_detach(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 
- 	HAL_INT tmp;
-@@ -1266,7 +1266,7 @@ static struct ieee80211vap *
- ath_vap_create(struct ieee80211com *ic, const char *name,
- 	int opmode, int flags, struct net_device *mdev, struct ieee80211vap *master)
- {
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct net_device *dev;
- 	struct ath_vap *avp;
-@@ -1344,7 +1344,7 @@ ath_vap_create(struct ieee80211com *ic,
- 		return NULL;
- 	}
- 
--	avp = dev->priv;
-+	avp = netdev_priv(dev);
- 	ieee80211_vap_setup(ic, dev, name, opmode, flags, master);
- 	/* override with driver methods */
- 	vap = &avp->av_vap;
-@@ -1571,7 +1571,7 @@ static void
- ath_vap_delete(struct ieee80211vap *vap)
- {
- 	struct net_device *dev = vap->iv_ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ath_vap *avp = ATH_VAP(vap);
- 	int decrease = 1;
-@@ -1673,7 +1673,7 @@ void
- ath_suspend(struct net_device *dev)
- {
- #ifdef AR_DEBUG
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- #endif
- 
- 	DPRINTF(sc, ATH_DEBUG_ANY, "flags=%x\n", dev->flags);
-@@ -1684,7 +1684,7 @@ void
- ath_resume(struct net_device *dev)
- {
- #ifdef AR_DEBUG
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- #endif
- 
- 	DPRINTF(sc, ATH_DEBUG_ANY, "flags=%x\n", dev->flags);
-@@ -2248,7 +2248,7 @@ ath_intr(int irq, void *dev_id, struct p
- #endif
- {
- 	struct net_device *dev = dev_id;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	u_int64_t hw_tsf = 0;
- 	HAL_INT status;
-@@ -2469,7 +2469,7 @@ static void
- ath_fatal_tasklet(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *)data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	EPRINTF(sc, "Hardware error; resetting.\n");
- 	ath_reset(dev);
-@@ -2479,7 +2479,7 @@ static void
- ath_rxorn_tasklet(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *)data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	EPRINTF(sc, "Receive FIFO overrun; resetting.\n");
- 	ath_reset(dev);
-@@ -2489,7 +2489,7 @@ static void
- ath_bmiss_tasklet(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *)data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	if (time_before(jiffies, sc->sc_ic.ic_bmiss_guard)) {
- 		/* Beacon miss interrupt occured too short after last beacon
-@@ -2568,7 +2568,7 @@ done:
- static int
- ath_init(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc->sc_ah;
- 	HAL_STATUS status;
-@@ -2693,7 +2693,7 @@ done:
- static int
- ath_stop_locked(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc->sc_ah;
- 
-@@ -2778,7 +2778,7 @@ static void ath_set_beacon_cal(struct at
- static int
- ath_stop(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	int error;
- 
- 	ATH_LOCK(sc);
-@@ -2998,7 +2998,7 @@ ath_fetch_idle_time(struct ath_softc *sc
- static int
- ath_reset(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ieee80211_channel *c;
-@@ -3164,7 +3164,7 @@ dot11_to_ratecode(struct ath_softc *sc,
- static int
- ath_tx_startraw(struct net_device *dev, struct ath_buf *bf, struct sk_buff *skb)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ieee80211_phy_params *ph = (struct ieee80211_phy_params *)
- 		(SKB_CB(skb) + 1); /* NB: SKB_CB casts to CB struct*. */
-@@ -3477,7 +3477,7 @@ _take_txbuf(struct ath_softc *sc, int fo
- static int
- ath_hardstart(struct sk_buff *skb, struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211_node *ni = NULL;
- 	struct ath_buf *bf = NULL;
- 	ath_bufhead bf_head;
-@@ -3792,7 +3792,7 @@ static int
- ath_mgtstart(struct ieee80211com *ic, struct sk_buff *skb)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_buf *bf = NULL;
- 	int error;
- 
-@@ -4151,7 +4151,7 @@ static ieee80211_keyix_t
- ath_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *k)
- {
- 	struct net_device *dev = vap->iv_ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	/*
- 	 * Group key allocation must be handled specially for
-@@ -4216,7 +4216,7 @@ ath_key_delete(struct ieee80211vap *vap,
- 				struct ieee80211_node *ninfo)
- {
- 	struct net_device *dev = vap->iv_ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ieee80211_node *ni = NULL;
- 	const struct ieee80211_cipher *cip = k->wk_cipher;
-@@ -4292,14 +4292,14 @@ ath_key_set(struct ieee80211vap *vap, co
- 	const u_int8_t mac[IEEE80211_ADDR_LEN])
- {
- 	struct net_device *dev = vap->iv_ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	return ath_keyset(sc, k, mac, vap->iv_bss);
- }
- 
- static void ath_poll_disable(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	/*
- 	 * XXX Using in_softirq is not right since we might
-@@ -4317,7 +4317,7 @@ static void ath_poll_disable(struct net_
- 
- static void ath_poll_enable(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	/* NB: see above */
- 	if (!in_softirq()) {
-@@ -4343,7 +4343,7 @@ ath_key_update_begin(struct ieee80211vap
- {
- 	struct net_device *dev = vap->iv_ic->ic_dev;
- #ifdef AR_DEBUG
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- #endif
- 
- 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "Begin\n");
-@@ -4361,7 +4361,7 @@ ath_key_update_end(struct ieee80211vap *
- {
- 	struct net_device *dev = vap->iv_ic->ic_dev;
- #ifdef AR_DEBUG
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- #endif
- 
- 	DPRINTF(sc, ATH_DEBUG_KEYCACHE, "End\n");
-@@ -4454,7 +4454,7 @@ ath_merge_mcast(struct ath_softc *sc, u_
- static void
- ath_mode_init(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	u_int32_t rfilt, mfilt[2];
- 
-@@ -4540,7 +4540,7 @@ ath_set_timing(struct ath_softc *sc)
- static void
- ath_updateslot(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 
- 	/*
-@@ -4570,7 +4570,7 @@ ath_beacon_dturbo_config(struct ieee8021
- 	(vap->iv_bss && (vap->iv_bss->ni_ath_flags & (IEEE80211_ATHC_TURBOP)) == \
- 		(IEEE80211_ATHC_TURBOP))
- 	struct ieee80211com *ic = vap->iv_ic;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 
- 	if (ic->ic_opmode == IEEE80211_M_HOSTAP && IS_CAPABLE(vap)) {
- 
-@@ -4618,7 +4618,7 @@ static void
- ath_beacon_dturbo_update(struct ieee80211vap *vap, int *needmark, u_int8_t dtim)
- {
- 	struct ieee80211com *ic = vap->iv_ic;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	u_int32_t bss_traffic;
- 
- 	if (sc->sc_ignore_ar) {
-@@ -4759,7 +4759,7 @@ static void
- ath_turbo_switch_mode(unsigned long data)
- {
- 	struct net_device *dev = (struct net_device *)data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	unsigned int newflags;
- 
-@@ -5438,7 +5438,7 @@ static void
- ath_bstuck_tasklet(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *)data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	/*
- 	 * XXX:if the bmisscount is cleared while the
- 	 *     tasklet execution is pending, the following
-@@ -5891,7 +5891,7 @@ ath_node_alloc_debug(struct ieee80211vap
- ath_node_alloc(struct ieee80211vap *vap)
- #endif 
- {
--	struct ath_softc *sc = vap->iv_ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(vap->iv_ic->ic_dev);
- 	const size_t space = sizeof(struct ath_node) + sc->sc_rc->arc_space;
- 	struct ath_node *an = kmalloc(space, GFP_ATOMIC);
- 	if (an != NULL) {
-@@ -5927,7 +5927,7 @@ ath_node_cleanup(struct ieee80211_node *
- #endif
- {
- 	struct ieee80211com *ic = ni->ni_ic;
--	struct ath_softc *sc = ni->ni_ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ni->ni_ic->ic_dev);
- 	struct ath_node *an = ATH_NODE(ni);
- 	struct ath_buf *bf;
- 
-@@ -5985,7 +5985,7 @@ ath_node_free_debug(struct ieee80211_nod
- ath_node_free(struct ieee80211_node *ni)
- #endif
- {
--	struct ath_softc *sc = ni->ni_ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ni->ni_ic->ic_dev);
- 
- #ifdef IEEE80211_DEBUG_REFCNT
- 	sc->sc_node_free_debug(ni, func, line);
-@@ -6033,7 +6033,7 @@ ath_node_move_data(const struct ieee8021
- #ifdef NOT_YET
- 	struct ath_txq *txq = NULL;
- 	struct ieee80211com *ic = ni->ni_ic;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	struct ath_buf *bf, *prev, *bf_tmp, *bf_tmp1;
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct sk_buff *skb = NULL;
-@@ -6553,7 +6553,7 @@ static void
- ath_capture(struct net_device *dev, const struct ath_buf *bf,
- 		struct sk_buff *skb, u_int64_t tsf, unsigned int tx)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct sk_buff *tskb = NULL;
-   
-@@ -6613,7 +6613,7 @@ static void
- ath_recv_mgmt(struct ieee80211vap * vap, struct ieee80211_node *ni_or_null,
- 	struct sk_buff *skb, int subtype, int rssi, u_int64_t rtsf)
- {
--	struct ath_softc *sc = vap->iv_ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(vap->iv_ic->ic_dev);
- #ifdef AR_DEBUG
-         struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
- #endif
-@@ -6780,7 +6780,7 @@ ath_rx_poll(struct net_device *dev, int
- 	struct net_device *dev = sc->sc_dev;
- 	int rx_limit = budget;
- #else
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	int rx_limit = min(dev->quota, *budget);
- #endif
- 	struct ath_buf *bf;
-@@ -7305,7 +7305,7 @@ static void ath_grppoll_start(struct iee
- 	struct sk_buff *skb = NULL;
- 	struct ath_buf *bf, *head = NULL;
- 	struct ieee80211com *ic = vap->iv_ic;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	u_int8_t rate;
- 	unsigned int ctsrate = 0, ctsduration = 0;
-@@ -7523,7 +7523,7 @@ static void ath_grppoll_start(struct iee
- static void ath_grppoll_stop(struct ieee80211vap *vap)
- {
- 	struct ieee80211com *ic = vap->iv_ic;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ath_txq *txq = &sc->sc_grpplq;
- 	struct ath_buf *bf;
-@@ -7735,7 +7735,7 @@ ath_txq_update(struct ath_softc *sc, str
- static int
- ath_wme_update(struct ieee80211com *ic)
- {
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 
- 	if (sc->sc_uapsdq)
- 		ath_txq_update(sc, sc->sc_uapsdq, WME_AC_VO);
-@@ -7754,7 +7754,7 @@ ath_uapsd_flush(struct ieee80211_node *n
- {
- 	struct ath_node *an = ATH_NODE(ni);
- 	struct ath_buf *bf;
--	struct ath_softc *sc = ni->ni_ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ni->ni_ic->ic_dev);
- 	struct ath_txq *txq;
- 
- 	ATH_NODE_UAPSD_LOCK_IRQ(an);
-@@ -7945,7 +7945,7 @@ ath_tx_start(struct net_device *dev, str
- 		struct ath_buf *bf, struct sk_buff *skb, int nextfraglen)
- {
- #define	MIN(a,b)	((a) < (b) ? (a) : (b))
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = ni->ni_ic;
- 	struct ieee80211vap *vap = ni->ni_vap;
- 	struct ath_hal *ah = sc->sc_ah;
-@@ -8854,7 +8854,7 @@ static void
- ath_tx_tasklet_q0(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *)data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	unsigned long flags;
- 
- process_tx_again:
-@@ -8885,7 +8885,7 @@ static void
- ath_tx_tasklet_q0123(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *)data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	unsigned long flags;
- 
- process_tx_again:
-@@ -8930,7 +8930,7 @@ static void
- ath_tx_tasklet(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *)data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	unsigned int i;
- 	unsigned long flags;
- 
-@@ -8958,7 +8958,7 @@ process_tx_again:
- static void
- ath_tx_timeout(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	if (ath_chan_unavail(sc))
- 		return;
-@@ -9366,7 +9366,7 @@ static void
- ath_calibrate(unsigned long arg)
- {
- 	struct net_device *dev = (struct net_device *)arg;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	/* u_int32_t nchans; */
-@@ -9441,7 +9441,7 @@ static void
- ath_scan_start(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	u_int32_t rfilt;
- 
-@@ -9461,7 +9461,7 @@ static void
- ath_scan_end(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	u_int32_t rfilt;
- 
-@@ -9479,7 +9479,7 @@ static void
- ath_set_channel(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	(void) ath_chan_set(sc, ic->ic_curchan);
- 	ic->ic_channoise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan));
-@@ -9496,7 +9496,7 @@ ath_set_channel(struct ieee80211com *ic)
- static void
- ath_set_coverageclass(struct ieee80211com *ic)
- {
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 
- 	sc->sc_coverage = ic->ic_coverageclass * 3;
- 	ath_set_timing(sc);
-@@ -9507,7 +9507,7 @@ ath_set_coverageclass(struct ieee80211co
- static u_int
- ath_mhz2ieee(struct ieee80211com *ic, u_int freq, u_int flags)
- {
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 
- 	return (ath_hal_mhz2ieee(sc->sc_ah, freq, flags));
- }
-@@ -9522,7 +9522,7 @@ ath_newstate(struct ieee80211vap *vap, e
- 	struct ath_vap *avp = ATH_VAP(vap);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ieee80211_node *ni, *wds_ni;
- 	unsigned int i;
-@@ -9962,7 +9962,7 @@ ath_setup_comp(struct ieee80211_node *ni
- {
- #define	IEEE80211_KEY_XR	(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV)
- 	struct ieee80211vap *vap = ni->ni_vap;
--	struct ath_softc *sc = vap->iv_ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(vap->iv_ic->ic_dev);
- 	struct ath_node *an = ATH_NODE(ni);
- 	ieee80211_keyix_t keyix;
- 
-@@ -10016,7 +10016,7 @@ static void
- ath_setup_stationkey(struct ieee80211_node *ni)
- {
- 	struct ieee80211vap *vap = ni->ni_vap;
--	struct ath_softc *sc = vap->iv_ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(vap->iv_ic->ic_dev);
- 	ieee80211_keyix_t keyix;
- 
- 	keyix = ath_key_alloc(vap, &ni->ni_ucastkey);
-@@ -10177,7 +10177,7 @@ ath_newassoc(struct ieee80211_node *ni,
- {
- 	struct ieee80211com *ic = ni->ni_ic;
- 	struct ieee80211vap *vap = ni->ni_vap;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 
- 	sc->sc_rc->ops->newassoc(sc, ATH_NODE(ni), isnew);
- 	ath_wprobe_node_join(ni->ni_vap, ni);
-@@ -10208,7 +10208,7 @@ ath_newassoc(struct ieee80211_node *ni,
- static int
- ath_getchannels(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc->sc_ah;
- 	HAL_CHANNEL *chans;
-@@ -10485,7 +10485,7 @@ ath_update_txpow(struct ath_softc *sc)
- static int
- ath_xr_rate_setup(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	const HAL_RATE_TABLE *rt;
-@@ -10516,7 +10516,7 @@ ath_xr_rate_setup(struct net_device *dev
- static int
- ath_rate_setup(struct net_device *dev, u_int mode)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	const HAL_RATE_TABLE *rt;
-@@ -10763,7 +10763,7 @@ ath_printtxbuf(const struct ath_buf *bf,
- {
- 	const struct ath_tx_status *ts = &bf->bf_dsstatus.ds_txstat;
- 	const struct ath_desc *ds = bf->bf_desc;
--	struct ath_softc *sc = bf->bf_node->ni_ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(bf->bf_node->ni_ic->ic_dev);
- 	u_int8_t status = done ? ts->ts_status : 0;
- 
- 	DPRINTF(sc, ATH_DEBUG_ANY, 
-@@ -10790,7 +10790,7 @@ ath_printtxbuf(const struct ath_buf *bf,
- static struct net_device_stats *
- ath_getstats(struct net_device *dev)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct net_device_stats *stats = &sc->sc_devstats;
- 
- 	/* update according to private statistics */
-@@ -10813,7 +10813,7 @@ ath_getstats(struct net_device *dev)
- static int
- ath_set_mac_address(struct net_device *dev, void *addr)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc->sc_ah;
- 	struct sockaddr *mac = addr;
-@@ -10842,7 +10842,7 @@ ath_set_mac_address(struct net_device *d
- static int
- ath_change_mtu(struct net_device *dev, int mtu)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	int error = 0;
- 
- 	if (!(ATH_MIN_MTU < mtu && mtu <= ATH_MAX_MTU)) {
-@@ -10929,7 +10929,7 @@ bad:
- static int
- ath_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	int error;
- 
-@@ -11810,7 +11810,7 @@ static void
- ath_announce(struct net_device *dev)
- {
- #define	HAL_MODE_DUALBAND	(HAL_MODE_11A|HAL_MODE_11B)
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct ath_hal *ah = sc->sc_ah;
- 	u_int modes, cc;
- 	static const int MLEN = 1024;
-@@ -11997,7 +11997,7 @@ static void
- txcont_configure_radio(struct ieee80211com *ic)
- {
- 	struct net_device           *dev = ic->ic_dev;
--	struct ath_softc            *sc = dev->priv;
-+	struct ath_softc            *sc = netdev_priv(dev);
- 	struct ath_hal              *ah = sc->sc_ah;
- 	struct ieee80211_wme_state  *wme = &ic->ic_wme;
- 	struct ieee80211vap         *vap = TAILQ_FIRST(&ic->ic_vaps);
-@@ -12271,7 +12271,7 @@ static void
- txcont_queue_packet(struct ieee80211com *ic, struct ath_txq* txq)
- {
- 	struct net_device *dev             = ic->ic_dev;
--	struct ath_softc *sc               = dev->priv;
-+	struct ath_softc *sc               = netdev_priv(dev);
- 	struct ath_hal *ah                 = sc->sc_ah;
- 	struct ath_buf *bf                 = NULL;
- 	struct sk_buff *skb                = NULL;
-@@ -12404,7 +12404,7 @@ static void
- txcont_on(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	if (IFF_RUNNING != (ic->ic_dev->flags & IFF_RUNNING)) {
- 		EPRINTF(sc, "Cannot enable txcont when"
-@@ -12425,7 +12425,7 @@ static void
- txcont_off(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	if (TAILQ_FIRST(&ic->ic_vaps)->iv_opmode != IEEE80211_M_WDS)
- 		sc->sc_beacons = 1;
-@@ -12439,7 +12439,7 @@ static int
- ath_get_dfs_testmode(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	return sc->sc_dfs_testmode;
- }
- 
-@@ -12466,7 +12466,7 @@ static void
- ath_set_dfs_testmode(struct ieee80211com *ic, int value)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	sc->sc_dfs_testmode = !!value;
- }
- 
-@@ -12476,7 +12476,7 @@ static int
- ath_get_txcont(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	return sc->sc_txcont;
- }
- 
-@@ -12494,7 +12494,7 @@ static void
- ath_set_txcont_power(struct ieee80211com *ic, unsigned int txpower)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	int new_txcont_power = txpower > IEEE80211_TXPOWER_MAX ? 
- 		IEEE80211_TXPOWER_MAX : txpower;
- 	if (sc->sc_txcont_power != new_txcont_power) {
-@@ -12512,7 +12512,7 @@ static int
- ath_get_txcont_power(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	/* VERY conservative default */
- 	return sc->sc_txcont_power ? sc->sc_txcont_power : 0;
- }
-@@ -12522,7 +12522,7 @@ ath_get_txcont_power(struct ieee80211com
- ath_set_txcont_rate(struct ieee80211com *ic, unsigned int new_rate)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	if (sc->sc_txcont_rate != new_rate) {
- 		/*  NOTE: This value is sanity checked and dropped down to 
- 		 *  closest rate in txcont_on. */
-@@ -12539,7 +12539,7 @@ ath_set_txcont_rate(struct ieee80211com
- ath_get_txcont_rate(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	return sc->sc_txcont_rate ? sc->sc_txcont_rate : 0;
- }
- 
-@@ -12549,7 +12549,7 @@ static void
- ath_set_dfs_cac_time(struct ieee80211com *ic, unsigned int time_s)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	sc->sc_dfs_cac_period = time_s;
- }
- 
-@@ -12559,7 +12559,7 @@ static unsigned int
- ath_get_dfs_cac_time(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	return sc->sc_dfs_cac_period;
- }
- 
-@@ -12579,7 +12579,7 @@ static void
- ath_set_dfs_excl_period(struct ieee80211com *ic, unsigned int time_s)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	sc->sc_dfs_excl_period = time_s;
- }
- 
-@@ -12588,7 +12588,7 @@ static unsigned int
- ath_get_dfs_excl_period(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	return sc->sc_dfs_excl_period;
- }
- 
-@@ -12600,7 +12600,7 @@ static unsigned int
- ath_test_radar(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc   = dev->priv;
-+	struct ath_softc *sc   = netdev_priv(dev);
- 	if ((ic->ic_flags & IEEE80211_F_DOTH) && (sc->sc_curchan.privFlags & CHANNEL_DFS))
- 		ath_radar_detected(sc, "ath_test_radar from user space");
- 	else
-@@ -12616,7 +12616,7 @@ static unsigned int
- ath_dump_hal_map(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc   = dev->priv;
-+	struct ath_softc *sc   = netdev_priv(dev);
- 	ath_hal_dump_map(sc->sc_ah);
- 	return 0;
- }
-@@ -12724,7 +12724,7 @@ ath_rcv_dev_event(struct notifier_block
- 	void *ptr)
- {
- 	struct net_device *dev = (struct net_device *)ptr;
--	struct ath_softc *sc = (struct ath_softc *)dev->priv;
-+	struct ath_softc *sc = (struct ath_softc *)netdev_priv(dev);
- 
- 	if (!dev || !sc || dev->open != &ath_init)
- 		return 0;
-@@ -13459,7 +13459,7 @@ static unsigned int
- ath_read_register(struct ieee80211com *ic, unsigned int address, 
- 		unsigned int* value)
- {
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	if (address >= MAX_REGISTER_ADDRESS) {
- 		IPRINTF(sc, "Illegal Atheros register access "
- 				"attempted: 0x%04x >= 0x%04x\n",
-@@ -13489,7 +13489,7 @@ static unsigned int
- ath_write_register(struct ieee80211com *ic, unsigned int address, 
- 		unsigned int value)
- {
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	if (address >= MAX_REGISTER_ADDRESS) {
- 		IPRINTF(sc, "Illegal Atheros register access "
- 				"attempted: 0x%04x >= 0x%04x\n",
-@@ -13517,7 +13517,7 @@ static void
- ath_registers_dump(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	ath_ar5212_registers_dump(sc);
- }
- #endif /* #ifdef ATH_REVERSE_ENGINEERING */
-@@ -13529,7 +13529,7 @@ static void
- ath_registers_mark(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	ath_ar5212_registers_mark(sc);
- }
- #endif /* #ifdef ATH_REVERSE_ENGINEERING */
-@@ -13541,7 +13541,7 @@ static void
- ath_registers_dump_delta(struct ieee80211com *ic)
- {
- 	struct net_device *dev = ic->ic_dev;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	ath_ar5212_registers_dump_delta(sc);
- }
- #endif /* #ifdef ATH_REVERSE_ENGINEERING */
---- a/ath/if_ath_pci.c
-+++ b/ath/if_ath_pci.c
-@@ -226,7 +226,7 @@ ath_pci_probe(struct pci_dev *pdev, cons
- 		printk(KERN_ERR "%s: no memory for device state\n", dev_info);
- 		goto bad2;
- 	}
--	sc = dev->priv;
-+	sc = netdev_priv(dev);
- 	sc->aps_sc.sc_dev = dev;
- 	sc->aps_sc.sc_iobase = mem;
- 
-@@ -309,7 +309,7 @@ static void
- ath_pci_remove(struct pci_dev *pdev)
- {
- 	struct net_device *dev = pci_get_drvdata(pdev);
--	struct ath_pci_softc *sc = dev->priv;
-+	struct ath_pci_softc *sc = netdev_priv(dev);
- 
- 	ath_detach(dev);
- 	if (dev->irq)
-@@ -327,7 +327,7 @@ ath_pci_suspend(struct pci_dev *pdev, pm
- 	struct net_device *dev = pci_get_drvdata(pdev);
- 
- 	ath_suspend(dev);
--	PCI_SAVE_STATE(pdev, ((struct ath_pci_softc *)dev->priv)->aps_pmstate);
-+	PCI_SAVE_STATE(pdev, ((struct ath_pci_softc *)netdev_priv(dev))->aps_pmstate);
- 	pci_disable_device(pdev);
- 	return pci_set_power_state(pdev, PCI_D3hot);
- }
-@@ -344,7 +344,7 @@ ath_pci_resume(struct pci_dev *pdev)
- 		return err;
- 
- 	/* XXX - Should this return nonzero on fail? */
--	PCI_RESTORE_STATE(pdev,	((struct ath_pci_softc *)dev->priv)->aps_pmstate);
-+	PCI_RESTORE_STATE(pdev,	((struct ath_pci_softc *)netdev_priv(dev))->aps_pmstate);
- 
- 	err = pci_enable_device(pdev);
- 	if (err)
---- a/ath/if_ath_radar.c
-+++ b/ath/if_ath_radar.c
-@@ -1533,7 +1533,7 @@ static void ath_rp_clear(struct ath_soft
- static void ath_rp_tasklet(TQUEUE_ARG data)
- {
- 	struct net_device *dev = (struct net_device *) data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 
- 	if (sc->sc_rp_analyse != NULL)
- 		sc->sc_rp_analyse(sc);
---- a/ath_rate/amrr/amrr.c
-+++ b/ath_rate/amrr/amrr.c
-@@ -298,7 +298,7 @@ ath_rate_ctl_start(struct ath_softc *sc,
- static void
- ath_rate_cb(void *arg, struct ieee80211_node *ni)
- {
--	ath_rate_update(ni->ni_ic->ic_dev->priv, ni, (long) arg);
-+	ath_rate_update(netdev_priv(ni->ni_ic->ic_dev), ni, (long) arg);
- }
- 
- /*
-@@ -308,7 +308,7 @@ static void
- ath_rate_newstate(struct ieee80211vap *vap, enum ieee80211_state state)
- {
- 	struct ieee80211com *ic = vap->iv_ic;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc;
- 	struct ieee80211_node *ni;
- 
-@@ -420,7 +420,7 @@ static void
- ath_ratectl(unsigned long data)
- {
- 	struct net_device *dev = (struct net_device *)data;
--	struct ath_softc *sc = dev->priv;
-+	struct ath_softc *sc = netdev_priv(dev);
- 	struct amrr_softc *asc = (struct amrr_softc *)sc->sc_rc;
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	int interval;
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -622,7 +622,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- static void
- ath_rate_cb(void *arg, struct ieee80211_node *ni)
- {
--		ath_rate_ctl_reset(ni->ni_ic->ic_dev->priv, ni);
-+		ath_rate_ctl_reset(netdev_priv(ni->ni_ic->ic_dev), ni);
- }
- 
- /* Reset the rate control state for each 802.11 state transition. */
-@@ -636,7 +636,7 @@ ath_rate_newstate(struct ieee80211vap *v
- 				/* Sync rates for associated stations and neighbors. */
- 				ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, NULL);
- 			}
--			ath_rate_newassoc(ic->ic_dev->priv, ATH_NODE(vap->iv_bss), 1);
-+			ath_rate_newassoc(netdev_priv(ic->ic_dev), ATH_NODE(vap->iv_bss), 1);
- 		}
- }
- 
-@@ -822,7 +822,7 @@ ath_proc_read_nodes(struct ieee80211vap
- 		unsigned int x = 0;
- 		unsigned int this_tp, this_prob, this_eprob;
- #ifdef AR_DEBUG
--			struct ath_softc *sc = vap->iv_ic->ic_dev->priv;;
-+			struct ath_softc *sc = netdev_priv(vap->iv_ic->ic_dev);
- #endif
- 
- 		IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
---- a/ath_rate/onoe/onoe.c
-+++ b/ath_rate/onoe/onoe.c
-@@ -281,7 +281,7 @@ ath_rate_ctl_start(struct ath_softc *sc,
- static void
- ath_rate_cb(void *arg, struct ieee80211_node *ni)
- {
--	ath_rate_update(ni->ni_ic->ic_dev->priv, ni, (long) arg);
-+	ath_rate_update(netdev_priv(ni->ni_ic->ic_dev), ni, (long) arg);
- }
- 
- /*
-@@ -291,7 +291,7 @@ static void
- ath_rate_newstate(struct ieee80211vap *vap, enum ieee80211_state state)
- {
- 	struct ieee80211com *ic = vap->iv_ic;
--	struct ath_softc *sc = ic->ic_dev->priv;
-+	struct ath_softc *sc = netdev_priv(ic->ic_dev);
- 	struct ieee80211_node *ni;
- 
- 	if (state == IEEE80211_S_INIT)
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -803,7 +803,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
- static void
- ath_rate_cb(void *arg, struct ieee80211_node *ni)
- {
--	ath_rate_ctl_reset(ni->ni_ic->ic_dev->priv, ni);
-+	ath_rate_ctl_reset(netdev_priv(ni->ni_ic->ic_dev), ni);
- }
- 
- /*
-@@ -821,7 +821,7 @@ ath_rate_newstate(struct ieee80211vap *v
- 			 */
- 			ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, NULL);
- 		}
--		ath_rate_newassoc(ic->ic_dev->priv, ATH_NODE(vap->iv_bss), 1);
-+		ath_rate_newassoc(netdev_priv(ic->ic_dev), ATH_NODE(vap->iv_bss), 1);
- 	}
- }
- 
---- a/include/compat.h
-+++ b/include/compat.h
-@@ -162,6 +162,10 @@ static inline int timeval_compare(struct
- #define IRQF_SHARED SA_SHIRQ
- #endif
- 
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27)
-+#define netdev_priv(_netdev) ((_netdev)->priv)
-+#endif
-+
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
- #define skb_end_pointer(_skb) ((_skb)->end)
- #define skb_tail_pointer(_skb) ((_skb)->tail)
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -458,7 +458,7 @@ ieee80211_vap_setup(struct ieee80211com
- #define	IEEE80211_C_OPMODE \
- 	(IEEE80211_C_IBSS | IEEE80211_C_HOSTAP | IEEE80211_C_AHDEMO | \
- 	 IEEE80211_C_MONITOR)
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct net_device *parent = ic->ic_dev;
- 	int err;
- 
-@@ -1355,7 +1355,7 @@ media_status(enum ieee80211_opmode opmod
- static void
- ieee80211com_media_status(struct net_device *dev, struct ifmediareq *imr)
- {
--	struct ieee80211com *ic = dev->priv;	/* XXX */
-+	struct ieee80211com *ic = netdev_priv(dev);	/* XXX */
- 
- 	imr->ifm_status = IFM_AVALID;
- 	if (!TAILQ_EMPTY(&ic->ic_vaps))
-@@ -1407,7 +1407,7 @@ media2mode(const struct ifmedia_entry *i
- static int
- ieee80211com_media_change(struct net_device *dev)
- {
--	struct ieee80211com *ic = dev->priv;	/* XXX */
-+	struct ieee80211com *ic = netdev_priv(dev);	/* XXX */
- 	struct ieee80211vap *vap;
- 	struct ifmedia_entry *ime = ic->ic_media.ifm_cur;
- 	enum ieee80211_phymode newphymode;
-@@ -1511,7 +1511,7 @@ checkrate(struct ieee80211com *ic, enum
- int
- ieee80211_media_change(struct net_device *dev)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ifmedia_entry *ime = vap->iv_media.ifm_cur;
- 	enum ieee80211_phymode newmode;
-@@ -1545,7 +1545,7 @@ EXPORT_SYMBOL(ieee80211_media_change);
- void
- ieee80211_media_status(struct net_device *dev, struct ifmediareq *imr)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	enum ieee80211_phymode mode;
- 	struct ieee80211_rateset *rs;
-@@ -1751,7 +1751,7 @@ EXPORT_SYMBOL(ieee80211_media2rate);
- static struct net_device_stats *
- ieee80211_getstats(struct net_device *dev)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct net_device_stats *stats = &vap->iv_devstats;
- 
- 	/* XXX: Total guess as to what to count where */
-@@ -1790,7 +1790,7 @@ ieee80211_change_mtu(struct net_device *
- static void
- ieee80211_set_multicast_list(struct net_device *dev)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct net_device *parent = ic->ic_dev;
- 
---- a/net80211/ieee80211_linux.c
-+++ b/net80211/ieee80211_linux.c
-@@ -183,7 +183,7 @@ EXPORT_SYMBOL(ieee80211_getmgtframe);
- static void
- ieee80211_vlan_register(struct net_device *dev, struct vlan_group *grp)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	vap->iv_vlgrp = grp;
- }
-@@ -194,7 +194,7 @@ ieee80211_vlan_register(struct net_devic
- static void
- ieee80211_vlan_add_vid(struct net_device *dev, unsigned short vid)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	if (vap->iv_vlgrp != NULL)
- 		vap->iv_bss->ni_vlan = vid;
-@@ -206,7 +206,7 @@ ieee80211_vlan_add_vid(struct net_device
- static void
- ieee80211_vlan_kill_vid(struct net_device *dev, unsigned short vid)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	if (vap->iv_vlgrp != NULL)
- 		vlan_group_set_device(vap->iv_vlgrp, vid, NULL);
-@@ -989,8 +989,8 @@ ieee80211_rcv_dev_event(struct notifier_
- 
- 	switch (event) {
- 	case NETDEV_CHANGENAME:
--		ieee80211_virtfs_vdetach(dev->priv);
--		ieee80211_virtfs_latevattach(dev->priv);
-+		ieee80211_virtfs_vdetach(netdev_priv(dev));
-+		ieee80211_virtfs_latevattach(netdev_priv(dev));
- 		return NOTIFY_DONE;
- 	default:
- 		break;
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -201,7 +201,7 @@ ieee80211_classify(struct ieee80211_node
- int
- ieee80211_hardstart(struct sk_buff *skb, struct net_device *dev)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct net_device *parent = ic->ic_dev;
- 	struct ieee80211_node *ni = NULL;
-@@ -317,7 +317,7 @@ bad:
-  */
- 
- void ieee80211_parent_queue_xmit(struct sk_buff *skb) {
--	struct ieee80211vap *vap = skb->dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(skb->dev);
- 
- 	vap->iv_devstats.tx_packets++;
- 	vap->iv_devstats.tx_bytes += skb->len;
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -970,7 +970,7 @@ ieee80211_init(struct net_device *dev, i
- {
- #define	IS_RUNNING(_dev) \
- 	((_dev->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct net_device *parent = ic->ic_dev;
- 
-@@ -1087,7 +1087,7 @@ ieee80211_init(struct net_device *dev, i
- int
- ieee80211_open(struct net_device *dev)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	return ieee80211_init(dev, 0);
- }
-@@ -1131,7 +1131,7 @@ EXPORT_SYMBOL(ieee80211_start_running);
- int
- ieee80211_stop(struct net_device *dev)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct net_device *parent = ic->ic_dev;
- 	struct ieee80211_node *tni, *ni;
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -87,7 +87,7 @@ pre_announced_chanswitch(struct net_devi
- static int
- preempt_scan(struct net_device *dev, int max_grace, int max_wait)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	int total_delay = 0;
- 	int canceled = 0, ready = 0;
-@@ -122,7 +122,7 @@ preempt_scan(struct net_device *dev, int
- static struct iw_statistics *
- ieee80211_iw_getstats(struct net_device *dev)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct iw_statistics *is = &vap->iv_iwstats;
- 	struct ieee80211com *ic = vap->iv_ic;
- 
-@@ -146,7 +146,7 @@ static int
- ieee80211_ioctl_giwname(struct net_device *dev, struct iw_request_info *info,
- 	char *name, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211_channel *c = vap->iv_ic->ic_curchan;
- 
- 	if (IEEE80211_IS_CHAN_108G(c))
-@@ -198,7 +198,7 @@ static int
- ieee80211_ioctl_siwencode(struct net_device *dev,
- 	struct iw_request_info *info, struct iw_point *erq, char *keybuf)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	int error;
- 	int wepchange = 0;
- 	ieee80211_keyix_t kix;
-@@ -306,7 +306,7 @@ static int
- ieee80211_ioctl_giwencode(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *erq, char *key)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211_key *k;
- 	int error;
- 	ieee80211_keyix_t kix;
-@@ -351,7 +351,7 @@ ieee80211_ioctl_siwrate(struct net_devic
- 		IFM_IEEE80211_11A | IFM_IEEE80211_TURBO,
- 		IFM_IEEE80211_11G | IFM_IEEE80211_TURBO,
- 	};
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ifreq ifr;
- 	int rate, retv;
-@@ -386,7 +386,7 @@ static int
- ieee80211_ioctl_giwrate(struct net_device *dev,	struct iw_request_info *info,
- 	struct iw_param *rrq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ifmediareq imr;
- 	int rate;
- 
-@@ -424,7 +424,7 @@ static int
- ieee80211_ioctl_siwrts(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_param *rts, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	u16 val;
- 
-@@ -447,7 +447,7 @@ static int
- ieee80211_ioctl_giwrts(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_param *rts, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	rts->value = vap->iv_rtsthreshold;
- 	rts->disabled = (rts->value == IEEE80211_RTS_MAX);
-@@ -460,7 +460,7 @@ static int
- ieee80211_ioctl_siwfrag(struct net_device *dev,	struct iw_request_info *info,
- 	struct iw_param *rts, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	u16 val;
- 
-@@ -483,7 +483,7 @@ static int
- ieee80211_ioctl_giwfrag(struct net_device *dev,	struct iw_request_info *info,
- 	struct iw_param *rts, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	rts->value = vap->iv_fragthreshold;
- 	rts->disabled = (rts->value == 2346);
-@@ -496,7 +496,7 @@ static int
- ieee80211_ioctl_siwap(struct net_device *dev, struct iw_request_info *info,
- 	struct sockaddr *ap_addr, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	/* NB: should not be set when in AP mode */
- 	if (vap->iv_opmode == IEEE80211_M_HOSTAP)
-@@ -532,7 +532,7 @@ static int
- ieee80211_ioctl_giwap(struct net_device *dev, struct iw_request_info *info,
- 	struct sockaddr *ap_addr, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	if (vap->iv_flags & IEEE80211_F_DESBSSID)
- 		IEEE80211_ADDR_COPY(&ap_addr->sa_data, vap->iv_des_bssid);
-@@ -553,7 +553,7 @@ static int
- ieee80211_ioctl_siwnickn(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *nickname)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	if (data->length > IEEE80211_NWID_LEN)
- 		return -E2BIG;
-@@ -569,7 +569,7 @@ static int
- ieee80211_ioctl_giwnickn(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *nickname)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	if (data->length > vap->iv_nicknamelen + 1)
- 		data->length = vap->iv_nicknamelen + 1;
-@@ -678,7 +678,7 @@ static int
- ieee80211_ioctl_siwfreq(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_freq *freq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_channel *c, *c2;
- 	int i;
-@@ -767,7 +767,7 @@ static int
- ieee80211_ioctl_giwfreq(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_freq *freq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 
- 	if (vap->iv_state == IEEE80211_S_RUN &&
-@@ -808,7 +808,7 @@ static int
- ieee80211_ioctl_siwessid(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *ssid)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	if (vap->iv_opmode == IEEE80211_M_WDS)
- 		return -EOPNOTSUPP;
-@@ -853,7 +853,7 @@ static int
- ieee80211_ioctl_giwessid(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *essid)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	if (vap->iv_opmode == IEEE80211_M_WDS)
- 		return -EOPNOTSUPP;
-@@ -899,7 +899,7 @@ static int
- ieee80211_ioctl_giwrange(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_node *ni = vap->iv_bss;
- 	struct iw_range *range = (struct iw_range *) extra;
-@@ -1047,7 +1047,7 @@ ieee80211_ioctl_setspy(struct net_device
- 	struct iw_point *data, char *extra)
- {
- 	/* save the list of node addresses */
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct sockaddr address[IW_MAX_SPY];
- 	unsigned int number = data->length;
- 	int i;
-@@ -1085,7 +1085,7 @@ ieee80211_ioctl_getspy(struct net_device
- 	 * locate nodes by mac (ieee80211_find_node()),
- 	 * copy out rssi, set updated flag appropriately
- 	 */
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta;
- 	struct ieee80211_node *ni;
- 	struct ieee80211com *ic = vap->iv_ic;
-@@ -1133,7 +1133,7 @@ static int
- ieee80211_ioctl_setthrspy(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct iw_thrspy threshold;
- 
- 	if (data->length != 1)
-@@ -1170,7 +1170,7 @@ static int
- ieee80211_ioctl_getthrspy(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct iw_thrspy *threshold;
- 
-@@ -1191,7 +1191,7 @@ static int
- ieee80211_ioctl_siwmode(struct net_device *dev, struct iw_request_info *info,
- 	__u32 *mode, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ifmediareq imr;
- 	int valid = 0;
- 
-@@ -1216,7 +1216,7 @@ static int
- ieee80211_ioctl_giwmode(struct net_device *dev,	struct iw_request_info *info,
- 	__u32 *mode, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ifmediareq imr;
- 
- 	memset(&imr, 0, sizeof(imr));
-@@ -1239,7 +1239,7 @@ static int
- ieee80211_ioctl_siwpower(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_param *wrq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 
- 	/* XXX: These values, flags, and caps do not seem to be used elsewhere 
-@@ -1278,7 +1278,7 @@ static int
- ieee80211_ioctl_giwpower(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_param *rrq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 
- 	rrq->disabled = (ic->ic_flags & IEEE80211_F_PMGTON) == 0;
-@@ -1302,7 +1302,7 @@ static int
- ieee80211_ioctl_siwretry(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_param *rrq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 
- 	if (rrq->disabled) {
-@@ -1334,7 +1334,7 @@ static int
- ieee80211_ioctl_giwretry(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_param *rrq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	rrq->disabled = (vap->iv_flags & IEEE80211_F_SWRETRY) == 0;
- 	if (!rrq->disabled) {
-@@ -1365,7 +1365,7 @@ static int
- ieee80211_ioctl_siwtxpow(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_param *rrq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	int fixed, disabled;
- 
-@@ -1402,7 +1402,7 @@ ieee80211_get_txcont(struct net_device *
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	params[0] = ic->ic_get_txcont(ic);
- 	return 0;
-@@ -1413,7 +1413,7 @@ ieee80211_get_dfs_cac_time(struct net_de
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	params[0] = ic->ic_get_dfs_cac_time(ic);
- 	return 0;
-@@ -1424,7 +1424,7 @@ ieee80211_get_dfs_excl_period(struct net
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	params[0] = ic->ic_get_dfs_excl_period(ic);
- 	return 0;
-@@ -1434,7 +1434,7 @@ ieee80211_set_dfs_cac_time(struct net_de
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	ic->ic_set_dfs_cac_time(ic, params[1]);
- 	return 0;
-@@ -1444,7 +1444,7 @@ ieee80211_set_dfs_excl_period  (struct n
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	ic->ic_set_dfs_excl_period(ic, params[1]);
- 	return 0;
-@@ -1455,7 +1455,7 @@ ieee80211_get_dfs_testmode(struct net_de
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	params[0] = ic->ic_get_dfs_testmode(ic);
- 	return 0;
-@@ -1466,7 +1466,7 @@ ieee80211_get_txcont_rate(struct net_dev
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	params[0] = ic->ic_get_txcont_rate(ic);
- 	return 0;
-@@ -1477,7 +1477,7 @@ ieee80211_set_txcont(struct net_device *
- 		void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	ic->ic_set_txcont(ic, params[1]);
- 	return 0;
-@@ -1488,7 +1488,7 @@ ieee80211_set_dfs_testmode(struct net_de
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	ic->ic_set_dfs_testmode(ic, params[1]);
- 	return 0;
-@@ -1499,7 +1499,7 @@ ieee80211_set_txcont_rate(struct net_dev
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	ic->ic_set_txcont_rate(ic, params[1]);
- 	return 0;
-@@ -1510,7 +1510,7 @@ ieee80211_set_txcont_power(struct net_de
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	ic->ic_set_txcont_power(ic, params[1]);
- 	return 0;
-@@ -1521,7 +1521,7 @@ ieee80211_get_txcont_power(struct net_de
- 		struct iw_request_info *info, void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	params[0] = ic->ic_get_txcont_power(ic);
- 	return 0;
-@@ -1533,7 +1533,7 @@ ieee80211_ioctl_hal_map(struct net_devic
-        void *w, char *extra)
- {
-        int *params = (int*) extra;
--       struct ieee80211vap *vap = dev->priv;
-+       struct ieee80211vap *vap = netdev_priv(dev);
-        struct ieee80211com *ic = vap->iv_ic;
-        params[0] = ic->ic_dump_hal_map(ic);
-        return 0;
-@@ -1545,7 +1545,7 @@ ieee80211_ioctl_radar(struct net_device
- 	void *w, char *extra)
- {
- 	int *params = (int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	if (!(ic->ic_flags & IEEE80211_F_DOTH))
- 		return 0;
-@@ -1557,7 +1557,7 @@ static int
- ieee80211_ioctl_giwtxpow(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_param *rrq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	unsigned int power = ic->ic_txpowlimit;
- 	struct ieee80211_channel *c;
-@@ -1581,7 +1581,7 @@ static int
- ieee80211_dump_registers(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
- {
- 	unsigned int *params = (unsigned int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	switch (params[1]) {
- 	case 2:
-@@ -1604,7 +1604,7 @@ static int
- ieee80211_ioctl_writereg(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
- {
- 	unsigned int *params = (unsigned int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	return ic->ic_write_register(ic, params[0], params[1]);
- }
-@@ -1615,7 +1615,7 @@ static int
- ieee80211_ioctl_readreg(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
- {
- 	unsigned int *params = (unsigned int*) extra;
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	return ic->ic_read_register(ic, params[0], &params[0]);
- }
-@@ -1651,7 +1651,7 @@ static int
- ieee80211_ioctl_iwaplist(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct waplistreq req;		/* XXX off stack */
- 
-@@ -1673,7 +1673,7 @@ static int
- ieee80211_ioctl_siwscan(struct net_device *dev,	struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	/*
- 	 * XXX don't permit a scan to be started unless we
-@@ -1997,7 +1997,7 @@ static int
- ieee80211_ioctl_giwscan(struct net_device *dev,	struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct iwscanreq req;
- 	int res = 0;
-@@ -2098,7 +2098,7 @@ static int
- ieee80211_ioctl_setmode(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *wri, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ifreq ifr;
- 	char s[6];		/* big enough for ``11adt'' */
-@@ -2222,10 +2222,10 @@ ieee80211_setathcap(struct ieee80211vap
- static int
- ieee80211_set_turbo(struct net_device *dev, int flag)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ifreq ifr;
--	struct ieee80211vap *tmpvap = dev->priv;
-+	struct ieee80211vap *tmpvap = netdev_priv(dev);
- 	int nvap = 0;
- 
- 	TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next)
-@@ -2246,7 +2246,7 @@ static int
- ieee80211_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
- 	unsigned int *i = (unsigned int *) extra;
-@@ -2926,7 +2926,7 @@ static int
- ieee80211_ioctl_getmode(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *wri, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ifmediareq imr;
- 
-@@ -2964,7 +2964,7 @@ static int
- ieee80211_ioctl_getparam(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
- 	unsigned int *param = (unsigned int *) extra;
-@@ -3309,7 +3309,7 @@ static int
- ieee80211_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *wri, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	void *ie;
- 
- 	/*
-@@ -3343,7 +3343,7 @@ static int
- ieee80211_ioctl_getoptie(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *wri, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	if (vap->iv_opt_ie == NULL) {
- 		wri->length = 0;
-@@ -3407,7 +3407,7 @@ ieee80211_ioctl_setappiebuf(struct net_d
- 	struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211req_getset_appiebuf *iebuf =
- 		(struct ieee80211req_getset_appiebuf *)extra;
- 	enum ieee80211_opmode chk_opmode;
-@@ -3449,7 +3449,7 @@ static int
- ieee80211_ioctl_getappiebuf(struct net_device *dev, struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211req_getset_appiebuf *iebuf =
- 		(struct ieee80211req_getset_appiebuf *)extra;
- 	int max_iebuf_len;
-@@ -3490,7 +3490,7 @@ static int
- ieee80211_ioctl_setfilter(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211req_set_filter *app_filter = (struct ieee80211req_set_filter *)extra;
- 
- 	if ((extra == NULL) || (app_filter->app_filterype & ~IEEE80211_FILTER_TYPE_ALL))
-@@ -3505,7 +3505,7 @@ static int
- ieee80211_ioctl_setkey(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211req_key *ik = (struct ieee80211req_key *)extra;
- 	struct ieee80211_node *ni;
-@@ -3588,7 +3588,7 @@ ieee80211_ioctl_setkey(struct net_device
- static int
- ieee80211_ioctl_getkey(struct net_device *dev, struct iwreq *iwr)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_node *ni;
- 	struct ieee80211req_key ik;
-@@ -3649,7 +3649,7 @@ static int
- ieee80211_ioctl_delkey(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211req_del_key *dk = (struct ieee80211req_del_key *)extra;
- 	ieee80211_keyix_t kix;
-@@ -3723,7 +3723,7 @@ static int
- ieee80211_ioctl_setmlme(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211req_mlme *mlme = (struct ieee80211req_mlme *)extra;
- 	struct ieee80211_node *ni;
-@@ -3826,7 +3826,7 @@ static int
- ieee80211_ioctl_wdsaddmac(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct sockaddr *sa = (struct sockaddr *)extra;
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211vap *avp;
-@@ -3855,7 +3855,7 @@ static int
- ieee80211_ioctl_wdssetmac(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct sockaddr *sa = (struct sockaddr *)extra;
- 
- 	if (vap->iv_opmode != IEEE80211_M_WDS)
-@@ -3922,7 +3922,7 @@ ieee80211_ioctl_setscanlist(struct net_d
- 	struct iw_request_info *info,
- 	struct iw_point *data, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	char *s, *next;
- 	int val = 1;
-@@ -3997,7 +3997,7 @@ static int
- ieee80211_ioctl_addmac(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct sockaddr *sa = (struct sockaddr *)extra;
- 	const struct ieee80211_aclator *acl = vap->iv_acl;
- 
-@@ -4015,7 +4015,7 @@ static int
- ieee80211_ioctl_delmac(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct sockaddr *sa = (struct sockaddr *)extra;
- 	const struct ieee80211_aclator *acl = vap->iv_acl;
- 
-@@ -4033,7 +4033,7 @@ static int
- ieee80211_ioctl_setchanlist(struct net_device *dev,
- 	struct iw_request_info *info, void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211req_chanlist *list =
- 		(struct ieee80211req_chanlist *)extra;
-@@ -4084,7 +4084,7 @@ static int
- ieee80211_ioctl_getchanlist(struct net_device *dev,
- 	struct iw_request_info *info, void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 
- 	memcpy(extra, ic->ic_chan_active, sizeof(ic->ic_chan_active));
-@@ -4105,7 +4105,7 @@ static int
- ieee80211_ioctl_getchaninfo(struct net_device *dev,
- 			    struct iw_request_info *info, void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211req_chaninfo *chans =
- 	    (struct ieee80211req_chaninfo *)extra;
-@@ -4152,7 +4152,7 @@ static int
- ieee80211_ioctl_setwmmparams(struct net_device *dev,
- 	struct iw_request_info *info, void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	unsigned int *param = (unsigned int *) extra;
- 	unsigned int ac = (param[1] < WME_NUM_AC) ? param[1] : WME_AC_BE;
- 	unsigned int bss = param[2];
-@@ -4240,7 +4240,7 @@ static int
- ieee80211_ioctl_getwmmparams(struct net_device *dev,
- 	struct iw_request_info *info, void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	unsigned int *param = (unsigned int *) extra;
- 	unsigned int ac = (param[1] < WME_NUM_AC) ? param[1] : WME_AC_BE;
- 	struct ieee80211_wme_state *wme = &vap->iv_ic->ic_wme;
-@@ -4275,7 +4275,7 @@ ieee80211_ioctl_getwmmparams(struct net_
- static int
- ieee80211_ioctl_getwpaie(struct net_device *dev, struct iwreq *iwr)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_node *ni;
- 	struct ieee80211req_wpaie wpaie;
-@@ -4309,7 +4309,7 @@ ieee80211_ioctl_getwpaie(struct net_devi
- static int
- ieee80211_ioctl_getstastats(struct net_device *dev, struct iwreq *iwr)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_node *ni;
- 	u_int8_t macaddr[IEEE80211_ADDR_LEN];
-@@ -4428,7 +4428,7 @@ get_scan_result(void *arg, const struct
- static int
- ieee80211_ioctl_getscanresults(struct net_device *dev, struct iwreq *iwr)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct scanreq req;
- 	int error;
-@@ -4591,7 +4591,7 @@ get_sta_info(void *arg, struct ieee80211
- static int
- ieee80211_ioctl_getstainfo(struct net_device *dev, struct iwreq *iwr)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct stainforeq req;
- 	int error;
-@@ -4625,7 +4625,7 @@ ieee80211_ioctl_getstainfo(struct net_de
- 
- static void
- pre_announced_chanswitch(struct net_device *dev, u_int32_t channel, u_int32_t tbtt) {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211vap *avp;
- 
-@@ -4643,7 +4643,7 @@ static int
- ieee80211_ioctl_chanswitch(struct net_device *dev, struct iw_request_info *info,
- 	void *w, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	unsigned int *param = (unsigned int *) extra;
- 
-@@ -4688,7 +4688,7 @@ static int
- ieee80211_ioctl_giwgenie(struct net_device *dev,
- 	struct iw_request_info *info, struct iw_point *out, char *buf)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 
- 	if (out->length < vap->iv_opt_ie_len)
- 		return -E2BIG;
-@@ -5221,7 +5221,7 @@ static int
- ieee80211_ioctl_giwencodeext(struct net_device *dev,
- 	struct iw_request_info *info, struct iw_point *erq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct iw_encode_ext *ext;
- 	struct ieee80211_key *wk;
- 	ieee80211_keyix_t kix;
-@@ -5281,7 +5281,7 @@ static int
- ieee80211_ioctl_siwencodeext(struct net_device *dev,
- 	struct iw_request_info *info, struct iw_point *erq, char *extra)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- 	struct ieee80211req_key kr;
- 	ieee80211_keyix_t kix;
-@@ -5957,7 +5957,7 @@ static struct iw_handler_def ieee80211_i
- static int
- ieee80211_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
--	struct ieee80211vap *vap = dev->priv;
-+	struct ieee80211vap *vap = netdev_priv(dev);
- 	struct ieee80211com *ic = vap->iv_ic;
- 	struct ieee80211_node *ni;
- 
diff --git a/package/madwifi/patches/431-compile_fixes.patch b/package/madwifi/patches/431-compile_fixes.patch
deleted file mode 100644
index b11d406a0d..0000000000
--- a/package/madwifi/patches/431-compile_fixes.patch
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -2388,7 +2388,9 @@ ath_intr(int irq, void *dev_id, struct p
- 		if (status & (HAL_INT_RX | HAL_INT_RXPHY)) {
- 			ath_uapsd_processtriggers(sc, hw_tsf);
- 			sc->sc_isr &= ~HAL_INT_RX;
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
-+			if (napi_schedule_prep(&sc->sc_napi))
-+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
- 			if (netif_rx_schedule_prep(dev, &sc->sc_napi))
- #else
- 			if (netif_rx_schedule_prep(dev))
-@@ -2396,7 +2398,9 @@ ath_intr(int irq, void *dev_id, struct p
- 			{
- 				sc->sc_imask &= ~HAL_INT_RX;
- 				ath_hal_intrset(ah, sc->sc_imask);
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
-+				__napi_schedule(&sc->sc_napi);
-+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
- 				__netif_rx_schedule(dev, &sc->sc_napi);
- #else
- 				__netif_rx_schedule(dev);
-@@ -7135,7 +7139,9 @@ rx_next:
- 		local_irq_restore(flags);
- 	}
- 
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
-+	napi_complete(napi);
-+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
- 	netif_rx_complete(dev, napi);
- #else
- 	netif_rx_complete(dev);
diff --git a/package/madwifi/patches/432-netdev_ops.patch b/package/madwifi/patches/432-netdev_ops.patch
deleted file mode 100644
index af829b164a..0000000000
--- a/package/madwifi/patches/432-netdev_ops.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-Convert to net_device_ops for Linux 2.6.29+
-http://madwifi-project.org/changeset/4005
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -566,6 +566,20 @@ static inline int rate_factor(int mode)
- 
- /* Initialize ath_softc structure */
- 
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
-+static const struct net_device_ops ath_netdev_ops = {
-+	.ndo_open		= ath_init,
-+	.ndo_stop		= ath_stop,
-+	.ndo_start_xmit		= ath_hardstart,
-+	.ndo_tx_timeout 	= ath_tx_timeout,
-+	.ndo_set_multicast_list = ath_mode_init,
-+	.ndo_do_ioctl		= ath_ioctl,
-+	.ndo_get_stats		= ath_getstats,
-+	.ndo_set_mac_address	= ath_set_mac_address,
-+	.ndo_change_mtu 	= ath_change_mtu,
-+};
-+#endif
-+
- int
- ath_attach(u_int16_t devid, struct net_device *dev, HAL_BUS_TAG tag)
- {
-@@ -865,16 +879,20 @@ ath_attach(u_int16_t devid, struct net_d
- 	}
- 
- 	/* NB: ether_setup is done by bus-specific code */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- 	dev->open = ath_init;
- 	dev->stop = ath_stop;
- 	dev->hard_start_xmit = ath_hardstart;
- 	dev->tx_timeout = ath_tx_timeout;
--	dev->watchdog_timeo = 5 * HZ;
- 	dev->set_multicast_list = ath_mode_init;
- 	dev->do_ioctl = ath_ioctl;
- 	dev->get_stats = ath_getstats;
- 	dev->set_mac_address = ath_set_mac_address;
- 	dev->change_mtu = ath_change_mtu;
-+#else
-+	dev->netdev_ops = &ath_netdev_ops;
-+#endif
-+	dev->watchdog_timeo = 5 * HZ;
- 	dev->tx_queue_len = ATH_TXBUF - ATH_TXBUF_MGT_RESERVED;
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
- 	netif_napi_add(dev, &sc->sc_napi, ath_rx_poll, 64);
-@@ -1257,7 +1275,6 @@ ath_detach(struct net_device *dev)
- 	ath_dynamic_sysctl_unregister(sc);
- 	ATH_LOCK_DESTROY(sc);
- 	ATH_HAL_LOCK_DESTROY(sc);
--	dev->stop = NULL; /* prevent calling ath_stop again */
- 	unregister_netdev(dev);
- 	return 0;
- }
-@@ -12732,8 +12749,13 @@ ath_rcv_dev_event(struct notifier_block
- 	struct net_device *dev = (struct net_device *)ptr;
- 	struct ath_softc *sc = (struct ath_softc *)netdev_priv(dev);
- 
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- 	if (!dev || !sc || dev->open != &ath_init)
- 		return 0;
-+#else
-+	if (!dev || !sc || dev->netdev_ops->ndo_open != &ath_init)
-+		return 0;
-+#endif
- 
- 	switch (event) {
- 	case NETDEV_CHANGENAME:
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -451,6 +451,18 @@ ieee80211_ifdetach(struct ieee80211com *
- }
- EXPORT_SYMBOL(ieee80211_ifdetach);
- 
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
-+static const struct net_device_ops ieee80211_netdev_ops = {
-+	.ndo_get_stats		= ieee80211_getstats,
-+	.ndo_open		= ieee80211_open,
-+	.ndo_stop		= ieee80211_stop,
-+	.ndo_start_xmit		= ieee80211_hardstart,
-+	.ndo_set_multicast_list = ieee80211_set_multicast_list,
-+	.ndo_change_mtu 	= ieee80211_change_mtu,
-+	.ndo_do_ioctl		= ieee80211_ioctl,
-+};
-+#endif
-+
- int
- ieee80211_vap_setup(struct ieee80211com *ic, struct net_device *dev,
- 	const char *name, int opmode, int flags, struct ieee80211vap *master)
-@@ -471,16 +483,21 @@ ieee80211_vap_setup(struct ieee80211com
- 		} else
- 			strncpy(dev->name, name, sizeof(dev->name));
- 	}
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- 
- 	dev->get_stats = ieee80211_getstats;
- 	dev->open = ieee80211_open;
- 	dev->stop = ieee80211_stop;
- 	dev->hard_start_xmit = ieee80211_hardstart;
- 	dev->set_multicast_list = ieee80211_set_multicast_list;
-+	dev->do_ioctl = ieee80211_ioctl;
- #if 0
- 	dev->set_mac_address = ieee80211_set_mac_address;
- #endif
-  	dev->change_mtu = ieee80211_change_mtu;
-+#else
-+	dev->netdev_ops = &ieee80211_netdev_ops;
-+#endif
- 	dev->tx_queue_len = 0;			/* NB: bypass queuing */
- 	dev->hard_header_len = parent->hard_header_len;
- 	/*
-@@ -1824,7 +1841,11 @@ ieee80211_set_multicast_list(struct net_
- 	IEEE80211_UNLOCK_IRQ(ic);
- 
- 	/* XXX: Merge multicast list into parent device */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- 	parent->set_multicast_list(ic->ic_dev);
-+#else
-+	parent->netdev_ops->ndo_set_multicast_list(ic->ic_dev);
-+#endif
- }
- 
- void
---- a/net80211/ieee80211_linux.c
-+++ b/net80211/ieee80211_linux.c
-@@ -984,8 +984,14 @@ ieee80211_rcv_dev_event(struct notifier_
- 	void *ptr)
- {
- 	struct net_device *dev = (struct net_device *) ptr;
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- 	if (!dev || dev->open != &ieee80211_open)
- 		return 0;
-+#else
-+	if (!dev || dev->netdev_ops->ndo_open != &ieee80211_open)
-+		return 0;
-+#endif
- 
- 	switch (event) {
- 	case NETDEV_CHANGENAME:
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -739,6 +739,7 @@ void ieee80211_build_sc_ie(struct ieee80
- void ieee80211_dfs_action(struct ieee80211com *);
- void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *);
- void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs);
-+int ieee80211_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
- 
- /*
-  * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers.
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -5954,7 +5954,7 @@ static struct iw_handler_def ieee80211_i
- /*
-  * Handle private ioctl requests.
-  */
--static int
-+int
- ieee80211_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
- 	struct ieee80211vap *vap = netdev_priv(dev);
-@@ -6044,7 +6044,6 @@ ieee80211_ioctl_vattach(struct ieee80211
- {
- 	struct net_device *dev = vap->iv_dev;
- 
--	dev->do_ioctl = ieee80211_ioctl;
- #if IW_HANDLER_VERSION < 7
- 	dev->get_wireless_stats = ieee80211_iw_getstats;
- #endif
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -1188,7 +1188,11 @@ ieee80211_deliver_data(struct ieee80211_
- 			skb1->protocol = __constant_htons(ETH_P_802_2);
- 			/* XXX insert vlan tag before queue it? */
- 			ni_tmp = SKB_CB(skb1)->ni; /* remember node so we can free it */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- 			ret = dev->hard_start_xmit(skb1, dev);
-+#else
-+			ret = dev->netdev_ops->ndo_start_xmit(skb1, dev);
-+#endif
- 
- 			if (ret == NETDEV_TX_BUSY)
- 				ieee80211_dev_kfree_skb(&skb1);
diff --git a/package/madwifi/patches/433-backport_remove_irq_none.patch b/package/madwifi/patches/433-backport_remove_irq_none.patch
deleted file mode 100644
index 5166d9e103..0000000000
--- a/package/madwifi/patches/433-backport_remove_irq_none.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-Fix Linux 2.6.30 compatibility
-
-Linux 2.6.30 doesn't define IRQ_NONE as a macro. Assume irqreturn_t,
-IRQ_NONE and IRQ_HANDLED to be present on Linux 2.6.29 and newer.
-http://madwifi-project.org/changeset/3986
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -83,11 +83,13 @@ typedef void *TQUEUE_ARG;
- /*
-  * Guess how the interrupt handler should work.
-  */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- #if !defined(IRQ_NONE)
- typedef void irqreturn_t;
- #define	IRQ_NONE
- #define	IRQ_HANDLED
- #endif /* !defined(IRQ_NONE) */
-+#endif /* Linux < 2.6.29 */
- 
- #ifndef SET_MODULE_OWNER
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
diff --git a/package/madwifi/patches/434-name-alloc-fix.patch b/package/madwifi/patches/434-name-alloc-fix.patch
deleted file mode 100644
index ab277630de..0000000000
--- a/package/madwifi/patches/434-name-alloc-fix.patch
+++ /dev/null
@@ -1,28 +0,0 @@
---- a/ath/if_ath_ahb.c
-+++ b/ath/if_ath_ahb.c
-@@ -311,6 +311,11 @@ init_ath_wmac(u_int16_t devid, u_int16_t
- 	SET_MODULE_OWNER(dev);
- 	sclist[wlanNum] = sc;
- 
-+	if (dev_alloc_name(dev, dev->name) < 0) {
-+		printk(KERN_ERR "%s: cannot allocate name\n", dev_info);
-+		goto bad3;
-+	}
-+
- 	switch (wlanNum) {
- 	case AR531X_WLAN0_NUM:
- 		if (((devid & AR5315_REV_MAJ_M) == AR5315_REV_MAJ) ||
---- a/ath/if_ath_pci.c
-+++ b/ath/if_ath_pci.c
-@@ -236,6 +236,11 @@ ath_pci_probe(struct pci_dev *pdev, cons
- 	 */
- 	sc->aps_sc.sc_invalid = 1;
- 
-+	if (dev_alloc_name(dev, dev->name) < 0) {
-+		printk(KERN_ERR "%s: cannot allocate name\n", dev_info);
-+		goto bad3;
-+	}
-+
- 	dev->irq = pdev->irq;
- 
- 	SET_MODULE_OWNER(dev);
diff --git a/package/madwifi/patches/435-ibss_neighbor_fix.patch b/package/madwifi/patches/435-ibss_neighbor_fix.patch
deleted file mode 100644
index d66af9b240..0000000000
--- a/package/madwifi/patches/435-ibss_neighbor_fix.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -313,7 +313,7 @@ ieee80211_input(struct ieee80211vap * va
- 			if (type == IEEE80211_FC0_TYPE_DATA && ni == vap->iv_bss &&
- 					!IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2)) {
- 				/* Try to find sender in local node table. */
--				ni = ieee80211_find_node(vap->iv_bss->ni_table, wh->i_addr2);
-+				ni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
- 				if (ni == NULL) {
- 					/*
- 					 * Fake up a node for this newly discovered
diff --git a/package/madwifi/patches/436-injection_checks.patch b/package/madwifi/patches/436-injection_checks.patch
deleted file mode 100644
index 2748731115..0000000000
--- a/package/madwifi/patches/436-injection_checks.patch
+++ /dev/null
@@ -1,26 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -3199,7 +3199,13 @@ ath_tx_startraw(struct net_device *dev,
- 	struct ieee80211_frame *wh;
- 
- 	wh = (struct ieee80211_frame *)skb->data;
-+
- 	try0 = ph->try0;
-+	if (!try0)
-+		try0 = 1;
-+	else if (try0 > 11)
-+		try0 = 11;
-+
- 	rt = sc->sc_currates;
- 	txrate = dot11_to_ratecode(sc, rt, ph->rate0);
- 	power = ph->power > 63 ? 63 : ph->power;
-@@ -3224,7 +3230,8 @@ ath_tx_startraw(struct net_device *dev,
- 	rt = sc->sc_currates;
- 	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
- 
--	if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-+	if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) ||
-+		IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- 		flags |= HAL_TXDESC_NOACK;	/* no ack on broad/multicast */
- 		sc->sc_stats.ast_tx_noack++;
- 		try0 = 1;
diff --git a/package/madwifi/patches/437-sysctl_cleanup.patch b/package/madwifi/patches/437-sysctl_cleanup.patch
deleted file mode 100644
index e35ed02937..0000000000
--- a/package/madwifi/patches/437-sysctl_cleanup.patch
+++ /dev/null
@@ -1,73 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -11021,38 +11021,38 @@ enum {
-  * mirrored in /proc/sys.
-  */
- enum {
--	ATH_SLOTTIME		= 1,
--	ATH_ACKTIMEOUT		= 2,
--	ATH_CTSTIMEOUT		= 3,
--	ATH_SOFTLED		= 4,
--	ATH_LEDPIN		= 5,
--	ATH_COUNTRYCODE		= 6,
--	ATH_REGDOMAIN		= 7,
--	ATH_DEBUG		= 8,
--	ATH_TXANTENNA		= 9,
--	ATH_RXANTENNA		= 10,
--	ATH_DIVERSITY		= 11,
--	ATH_TXINTRPERIOD	= 12,
--	ATH_FFTXQMIN		= 13,
--	ATH_XR_POLL_PERIOD	= 14,
--	ATH_XR_POLL_COUNT	= 15,
--	ATH_ACKRATE		= 16,
--	ATH_RP         		= 17,
--	ATH_RP_PRINT   		= 18,
--	ATH_RP_PRINT_ALL 	= 19,
--	ATH_RP_PRINT_MEM 	= 20,
--	ATH_RP_PRINT_MEM_ALL 	= 21,
--	ATH_RP_FLUSH   		= 22,
--	ATH_PANIC               = 23,
--	ATH_RP_IGNORED 		= 24,
--	ATH_RADAR_IGNORED       = 25,
--	ATH_MAXVAPS  		= 26,
--	ATH_INTMIT			= 27,
--	ATH_NOISE_IMMUNITY	= 28,
--	ATH_OFDM_WEAK_DET	= 29,
--	ATH_CHANBW		= 30,
--	ATH_OUTDOOR		= 31,
--	ATH_DISTANCE	= 32,
-+	ATH_SLOTTIME,
-+	ATH_ACKTIMEOUT,
-+	ATH_CTSTIMEOUT,
-+	ATH_SOFTLED,
-+	ATH_LEDPIN,
-+	ATH_COUNTRYCODE,
-+	ATH_REGDOMAIN,
-+	ATH_DEBUG,
-+	ATH_TXANTENNA,
-+	ATH_RXANTENNA,
-+	ATH_DIVERSITY,
-+	ATH_TXINTRPERIOD,
-+	ATH_FFTXQMIN,
-+	ATH_XR_POLL_PERIOD,
-+	ATH_XR_POLL_COUNT,
-+	ATH_ACKRATE,
-+	ATH_RP,
-+	ATH_RP_PRINT,
-+	ATH_RP_PRINT_ALL,
-+	ATH_RP_PRINT_MEM,
-+	ATH_RP_PRINT_MEM_ALL,
-+	ATH_RP_FLUSH,
-+	ATH_PANIC,
-+	ATH_RP_IGNORED,
-+	ATH_RADAR_IGNORED,
-+	ATH_MAXVAPS,
-+	ATH_INTMIT,
-+	ATH_NOISE_IMMUNITY,
-+	ATH_OFDM_WEAK_DET,
-+	ATH_CHANBW,
-+	ATH_OUTDOOR,
-+	ATH_DISTANCE,
- };
- 
- /*
diff --git a/package/madwifi/patches/438-poweroffset_sysctl.patch b/package/madwifi/patches/438-poweroffset_sysctl.patch
deleted file mode 100644
index e82046ec6b..0000000000
--- a/package/madwifi/patches/438-poweroffset_sysctl.patch
+++ /dev/null
@@ -1,59 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -10476,11 +10476,11 @@ set_node_txpower(void *arg, struct ieee8
-  * XXX: this function needs some locking to avoid being called 
-  * twice/interrupted. Returns the value actually stored. */
- static u_int32_t
--ath_set_clamped_maxtxpower(struct ath_softc *sc, 
--		u_int32_t new_clamped_maxtxpower)
-+ath_set_clamped_maxtxpower(struct ath_softc *sc, u_int32_t new_txpwr)
- {
--	new_clamped_maxtxpower -= sc->sc_poweroffset;
--	(void)ath_hal_settxpowlimit(sc->sc_ah, new_clamped_maxtxpower);
-+	new_txpwr = ((new_txpwr < sc->sc_poweroffset) ? 0 :
-+		new_txpwr - sc->sc_poweroffset);
-+	(void)ath_hal_settxpowlimit(sc->sc_ah, new_txpwr);
- 	return ath_get_clamped_maxtxpower(sc);
- }
- 
-@@ -11031,6 +11031,7 @@ enum {
- 	ATH_DEBUG,
- 	ATH_TXANTENNA,
- 	ATH_RXANTENNA,
-+	ATH_POWEROFFSET,
- 	ATH_DIVERSITY,
- 	ATH_TXINTRPERIOD,
- 	ATH_FFTXQMIN,
-@@ -11311,6 +11312,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 				ath_debug_global = (val &  ATH_DEBUG_GLOBAL);
- #endif
- 				break;
-+			case ATH_POWEROFFSET:
-+				sc->sc_poweroffset = val;
-+				break;
- 			case ATH_TXANTENNA:
- 				/*
- 				 * antenna can be:
-@@ -11478,6 +11482,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 		case ATH_DEBUG:
- 			val = sc->sc_debug | ath_debug_global;
- 			break;
-+		case ATH_POWEROFFSET:
-+			val = sc->sc_poweroffset;
-+			break;
- 		case ATH_TXANTENNA:
- 			val = sc->sc_txantenna;
- 			break;
-@@ -11619,6 +11626,12 @@ static const ctl_table ath_sysctl_templa
- 	},
- #endif
- 	{ .ctl_name	= CTL_AUTO,
-+	  .procname	= "poweroffset",
-+	  .mode		= 0644,
-+	  .proc_handler	= ath_sysctl_halparam,
-+	  .extra2	= (void *)ATH_POWEROFFSET,
-+	},
-+	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "txantenna",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
diff --git a/package/madwifi/patches/439-wlanconfig_stack_usage.patch b/package/madwifi/patches/439-wlanconfig_stack_usage.patch
deleted file mode 100644
index f346143c3f..0000000000
--- a/package/madwifi/patches/439-wlanconfig_stack_usage.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/tools/wlanconfig.c
-+++ b/tools/wlanconfig.c
-@@ -560,7 +560,7 @@ ieee80211_ntoa(const uint8_t mac[IEEE802
- static void
- list_stations(const char *ifname)
- {
--	uint8_t buf[24*1024];
-+	static uint8_t buf[24*1024];
- 	struct iwreq iwr;
- 	uint8_t *cp;
- 	int s, len;
-@@ -653,7 +653,7 @@ list_stations(const char *ifname)
- static void
- list_scan(const char *ifname)
- {
--	uint8_t buf[24 * 1024];
-+	static uint8_t buf[24 * 1024];
- 	char ssid[14];
- 	uint8_t *cp;
- 	int len;
diff --git a/package/madwifi/patches/440-wme_cleanup.patch b/package/madwifi/patches/440-wme_cleanup.patch
deleted file mode 100644
index bb81ac7f81..0000000000
--- a/package/madwifi/patches/440-wme_cleanup.patch
+++ /dev/null
@@ -1,136 +0,0 @@
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -73,6 +73,29 @@ doprint(struct ieee80211vap *vap, int su
- }
- #endif
- 
-+static const int ieee802_1d_to_ac[8] = {
-+	WME_AC_BE, WME_AC_BK, WME_AC_BK, WME_AC_BE,
-+	WME_AC_VI, WME_AC_VI, WME_AC_VO, WME_AC_VO
-+};
-+
-+/* Given a data frame determine the 802.1p/1d tag to use. */
-+static unsigned int ieee80211_classify_ip(struct sk_buff *skb)
-+{
-+	const struct ether_header *eh = (struct ether_header *) skb->data;
-+	const struct iphdr *ip = (struct iphdr *)
-+			(skb->data + sizeof (struct ether_header));
-+	unsigned int dscp;
-+
-+	switch (skb->protocol) {
-+	case __constant_htons(ETH_P_IP):
-+		dscp = ip->tos & 0xfc;
-+		break;
-+	default:
-+		return 0;
-+	}
-+
-+	return dscp >> 5;
-+}
- 
- /*
-  * Determine the priority based on VLAN and/or IP TOS. Priority is
-@@ -83,90 +106,24 @@ static int
- ieee80211_classify(struct ieee80211_node *ni, struct sk_buff *skb)
- {
- 	struct ieee80211vap *vap = ni->ni_vap;
--	struct ether_header *eh = (struct ether_header *) skb->data;
--	int v_wme_ac = 0, d_wme_ac = 0;
- 
--	/* default priority */
--	skb->priority = WME_AC_BE;
--
--	if (!(ni->ni_flags & IEEE80211_NODE_QOS))
--		return 0;
--
--	/* 
--	 * If node has a vlan tag then all traffic
--	 * to it must have a matching vlan id.
-+	/* skb->priority values from 256->263 are magic values to
-+	 * directly indicate a specific 802.1d priority.  This is used
-+	 * to allow 802.1d priority to be passed directly in from VLAN
-+	 * tags, etc.
- 	 */
--	if (ni->ni_vlan != 0 && vlan_tx_tag_present(skb)) {
--		u_int32_t tag=0;
--		int v_pri;
--
--		if (vap->iv_vlgrp == NULL) {
--			IEEE80211_NODE_STAT(ni, tx_novlantag);
--			ni->ni_stats.ns_tx_novlantag++;
--			return 1;
--		}
--		if (((tag = vlan_tx_tag_get(skb)) & VLAN_VID_MASK) !=
--		    (ni->ni_vlan & VLAN_VID_MASK)) {
--			IEEE80211_NODE_STAT(ni, tx_vlanmismatch);
--			ni->ni_stats.ns_tx_vlanmismatch++;
--			return 1;
--		}
--		if (ni->ni_flags & IEEE80211_NODE_QOS) {
--			v_pri = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
--			switch (v_pri) {
--			case 1:
--			case 2:		/* Background (BK) */
--				v_wme_ac = WME_AC_BK;
--				break;
--			case 0:
--			case 3:		/* Best Effort (BE) */
--				v_wme_ac = WME_AC_BE;
--				break;
--			case 4:
--			case 5:		/* Video (VI) */
--				v_wme_ac = WME_AC_VI;
--				break;
--			case 6:
--			case 7:		/* Voice (VO) */
--				v_wme_ac = WME_AC_VO;
--				break;
--			}
--		}
-+	if (skb->priority >= 256 && skb->priority <= 263) {
-+		skb->priority = ieee802_1d_to_ac[skb->priority - 256];
-+		return 0;
- 	}
- 
--	if (eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
--		const struct iphdr *ip = (struct iphdr *)
--			(skb->data + sizeof (struct ether_header));
--		/*
--		 * IP frame, map the TOS field.
--		 *
--		 * XXX: fill out these mappings???
--		 */
--		switch (ip->tos) {
--		case 0x08:				/* Background */
--		case 0x20:
--			d_wme_ac = WME_AC_BK;
--			break;
--		case 0x28:				/* Video */
--		case 0xa0:
--			d_wme_ac = WME_AC_VI;
--			break;
--		case 0x30:				/* Voice */
--		case 0xe0:
--		case 0x88:				/* XXX UPSD */
--		case 0xb8:
--			d_wme_ac = WME_AC_VO;
--			break;
--		default:				/* All others */
--			d_wme_ac = WME_AC_BE;
--			break;
--		}
--	} else {
--		d_wme_ac = WME_AC_BE;
-+	if (!(ni->ni_flags & IEEE80211_NODE_QOS)) {
-+		/* default priority */
-+		skb->priority = WME_AC_BE;
-+		return 0;
- 	}
--	skb->priority = d_wme_ac;
--	if (v_wme_ac > d_wme_ac)
--		skb->priority = v_wme_ac;
-+
-+	skb->priority = ieee802_1d_to_ac[ieee80211_classify_ip(skb)];
- 
- 	/* Applying ACM policy */
- 	if (vap->iv_opmode == IEEE80211_M_STA) {
diff --git a/package/madwifi/patches/441-fix_ibss_node_handling.patch b/package/madwifi/patches/441-fix_ibss_node_handling.patch
deleted file mode 100644
index 20d59de26b..0000000000
--- a/package/madwifi/patches/441-fix_ibss_node_handling.patch
+++ /dev/null
@@ -1,91 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -6641,10 +6641,8 @@ static void
- ath_recv_mgmt(struct ieee80211vap * vap, struct ieee80211_node *ni_or_null,
- 	struct sk_buff *skb, int subtype, int rssi, u_int64_t rtsf)
- {
-+	const struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
- 	struct ath_softc *sc = netdev_priv(vap->iv_ic->ic_dev);
--#ifdef AR_DEBUG
--        struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
--#endif
- 	struct ieee80211_node * ni = ni_or_null;
- 	u_int64_t hw_tsf, beacon_tsf;
- 	u_int32_t hw_tu, beacon_tu, intval;
-@@ -6686,7 +6684,7 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 		}
- 		if ((vap->iv_opmode == IEEE80211_M_IBSS) &&
- 				(sc->sc_opmode == HAL_M_HOSTAP) &&
--				IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) {
-+				IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid)) {
- 			/* In this mode, we drive the HAL in HOSTAP mode. Hence
- 			 * we do the IBSS merging in software. Also do not merge
- 			 * if the difference it too small. Otherwise we are playing
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -311,7 +311,8 @@ ieee80211_input(struct ieee80211vap * va
- 			}
- 			/* Do not try to find a node reference if the packet really did come from the BSS */
- 			if (type == IEEE80211_FC0_TYPE_DATA && ni == vap->iv_bss &&
--					!IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2)) {
-+					!IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2) &&
-+					IEEE80211_ADDR_EQ(vap->iv_bssid, wh->i_addr3)) {
- 				/* Try to find sender in local node table. */
- 				ni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
- 				if (ni == NULL) {
-@@ -513,6 +514,10 @@ ieee80211_input(struct ieee80211vap * va
- 			break;
- 		case IEEE80211_M_IBSS:
- 		case IEEE80211_M_AHDEMO:
-+			/* ignore foreign data frames */
-+			if (ni == vap->iv_bss)
-+				goto out;
-+
- 			if (dir != IEEE80211_FC1_DIR_NODS) {
- 				IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
- 					wh, "data", "invalid dir 0x%x", dir);
-@@ -3558,6 +3563,11 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			} else if ((vap->iv_opmode == IEEE80211_M_WDS) && vap->iv_wdsnode) {
- 				found = 1;
- 				ni = ni_or_null = vap->iv_wdsnode;
-+			} else if (vap->iv_opmode == IEEE80211_M_IBSS) {
-+				ni_or_null = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
-+				if (ni_or_null)
-+					ni = ni_or_null;
-+				found = 1;
- 			}
- 			IEEE80211_UNLOCK_IRQ(vap->iv_ic);
- 
-@@ -3686,19 +3696,8 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			vap->iv_stats.is_rx_ssidmismatch++; /*XXX*/
- 			return;
- 		}
--		if (ni == vap->iv_bss) {
--			if (vap->iv_opmode == IEEE80211_M_IBSS) {
--				/*
--				 * XXX Cannot tell if the sender is operating
--				 * in ibss mode.  But we need a new node to
--				 * send the response so blindly add them to the
--				 * neighbor table.
--				 */
--				ni = ieee80211_fakeup_adhoc_node(vap,
--					wh->i_addr2);
--			} else {
--				ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
--			}
-+		if (ni == vap->iv_bss && vap->iv_opmode != IEEE80211_M_IBSS) {
-+			ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
- 			if (ni == NULL)
- 				return;
- 			allocbs = 1;
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -601,6 +601,8 @@ ieee80211_ibss_merge(struct ieee80211_no
- 		ic->ic_flags & IEEE80211_F_SHPREAMBLE ? "short" : "long",
- 		ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long",
- 		ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : "");
-+	if (!IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bssid))
-+		ieee80211_node_table_reset(&vap->iv_ic->ic_sta, vap);
- 	return ieee80211_sta_join1(ieee80211_ref_node(ni));
- }
- EXPORT_SYMBOL(ieee80211_ibss_merge);
diff --git a/package/madwifi/patches/442-ibss_rx_filter.patch b/package/madwifi/patches/442-ibss_rx_filter.patch
deleted file mode 100644
index eaf807118f..0000000000
--- a/package/madwifi/patches/442-ibss_rx_filter.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -294,6 +294,17 @@ ieee80211_input(struct ieee80211vap * va
- 			break;
- 		case IEEE80211_M_IBSS:
- 		case IEEE80211_M_AHDEMO:
-+			if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid) ||
-+			    (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr) &&
-+			     !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
-+			     (subtype != IEEE80211_FC0_SUBTYPE_BEACON))) {
-+				if (!(vap->iv_dev->flags & IFF_PROMISC)) {
-+					IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
-+						bssid, NULL, "%s", "not to bss");
-+					vap->iv_stats.is_rx_wrongbss++;
-+					goto out;
-+				}
-+			}
- 			if (dir != IEEE80211_FC1_DIR_NODS)
- 				bssid = wh->i_addr1;
- 			else if (type == IEEE80211_FC0_TYPE_CTL)
diff --git a/package/madwifi/patches/443-tx_drop_counter.patch b/package/madwifi/patches/443-tx_drop_counter.patch
deleted file mode 100644
index 30630ae43c..0000000000
--- a/package/madwifi/patches/443-tx_drop_counter.patch
+++ /dev/null
@@ -1,25 +0,0 @@
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -1592,10 +1592,6 @@ found:
- 				ieee80211_ref_node(ni);
- #endif
- 			}
--		} else {
--			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_OUTPUT, mac,
--				"no node, discard frame (%s)", __func__);
--			vap->iv_stats.is_tx_nonode++;
- 		}
- 	}
- 	return ni;
---- a/net80211/ieee80211_output.c
-+++ b/net80211/ieee80211_output.c
-@@ -208,6 +208,9 @@ ieee80211_hardstart(struct sk_buff *skb,
- 	ni = ieee80211_find_txnode(vap, eh->ether_dhost);
- 	if (ni == NULL) {
- 		/* NB: ieee80211_find_txnode does stat+msg */
-+		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_OUTPUT, mac,
-+			"no node, discard frame (%s)", __func__);
-+		vap->iv_stats.is_tx_nonode++;
- 		goto bad;
- 	}
- 
diff --git a/package/madwifi/patches/444-beacon_update_war.patch b/package/madwifi/patches/444-beacon_update_war.patch
deleted file mode 100644
index 6a3178a6db..0000000000
--- a/package/madwifi/patches/444-beacon_update_war.patch
+++ /dev/null
@@ -1,17 +0,0 @@
---- a/net80211/ieee80211_beacon.c
-+++ b/net80211/ieee80211_beacon.c
-@@ -476,6 +476,14 @@ ieee80211_beacon_update(struct ieee80211
- 			tie->tim_bitctl |= BITCTL_BUFD_MCAST;
- 		else
- 			tie->tim_bitctl &= ~BITCTL_BUFD_MCAST;
-+
-+		/* WAR: on some platforms, a race condition between beacon
-+		 * contents update and beacon transmission leads to beacon
-+		 * data not being updated in time. For most fields this is
-+		 * not critical, but for powersave it is. Work around this
-+		 * by always remapping the beacon when the TIM IE changes.
-+		 */
-+		len_changed = 1;
- 	}
- 
- 	/* Whenever we want to switch to a new channel, we need to follow the
diff --git a/package/madwifi/patches/445-fix_ps_sta_count.patch b/package/madwifi/patches/445-fix_ps_sta_count.patch
deleted file mode 100644
index 27514650a5..0000000000
--- a/package/madwifi/patches/445-fix_ps_sta_count.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -1957,6 +1957,7 @@ ath_uapsd_processtriggers(struct ath_sof
- 				if (qwh->i_fc[1] & IEEE80211_FC1_PWR_MGT) {
- 					ni->ni_flags |=
- 						IEEE80211_NODE_UAPSD_TRIG;
-+					ni->ni_vap->iv_ps_sta++;
- 					ic->ic_uapsdmaxtriggers++;
- 					WME_UAPSD_NODE_TRIGSEQINIT(ni);
- 					DPRINTF(sc, ATH_DEBUG_UAPSD,
-@@ -1967,6 +1968,7 @@ ath_uapsd_processtriggers(struct ath_sof
- 				} else {
- 					ni->ni_flags &=
- 						~IEEE80211_NODE_UAPSD_TRIG;
-+					ni->ni_vap->iv_ps_sta--;
- 					ic->ic_uapsdmaxtriggers--;
- 					DPRINTF(sc, ATH_DEBUG_UAPSD,
- 						"Node (" MAC_FMT ") no longer U-APSD"
diff --git a/package/madwifi/patches/446-single_module.patch b/package/madwifi/patches/446-single_module.patch
deleted file mode 100644
index b2898ca7eb..0000000000
--- a/package/madwifi/patches/446-single_module.patch
+++ /dev/null
@@ -1,778 +0,0 @@
---- a/ath/Makefile
-+++ b/ath/Makefile
-@@ -41,7 +41,6 @@
- #
- 
- obj := $(firstword $(obj) $(SUBDIRS) .)
--TOP = $(obj)/..
- 
- ifeq ($(strip $(BUS)),AHB)
- BUSNAME=ahb
-@@ -57,7 +56,24 @@ COPTS	+= -DDFS_DOMAIN_ETSI -DDFS_DOMAIN_
- include $(TOP)/Makefile.inc
- 
- obj-m		+= ath_$(BUSNAME).o
--ath_$(BUSNAME)-objs	:= if_ath.o if_ath_radar.o if_ath_$(BUSNAME).o
-+ath_objs := if_ath.o if_ath_radar.o if_ath_$(BUSNAME).o
-+ath_$(BUSNAME)-objs	:= $(ath_objs)
-+
-+ifneq ($(SINGLE_MODULE),)
-+include $(TOP)/net80211/Makefile
-+include $(TOP)/ath_rate/sample/Makefile
-+include $(TOP)/ath_rate/minstrel/Makefile
-+RC_DECLARE=$(foreach R,$(ATH_RATE),extern void ath_rate_$(R)_init(void);extern void ath_rate_$(R)_exit(void);)
-+RC_INIT=$(foreach R,$(ATH_RATE),ath_rate_$(R)_init();)
-+RC_EXIT=$(foreach R,$(ATH_RATE),ath_rate_$(R)_exit();)
-+
-+ath_$(BUSNAME)-objs += $(patsubst %,../net80211/%,$(wlan-objs) $(foreach var,wep tkip ccmp acl xauth scan_sta scan_ap,$(wlan_$(var)-objs))) $(foreach RC,$(ATH_RATE),$(patsubst %,../ath_rate/$(RC)/%,$(ath_rate_$(RC)-objs)))
-+ifdef LINUX24
-+  ath_$(BUSNAME)-linkobjs := $(ath_objs) $(wlan-objs) $(foreach var,wep tkip ccmp acl xauth scan_sta scan_ap,$(wlan_$(var)-objs)) $(foreach RC,$(ATH_RATE),$(ath_rate_$(RC)-objs))
-+endif
-+
-+EXTRA_CFLAGS += -DSINGLE_MODULE -DRC_INIT="$(RC_INIT)" -DRC_EXIT="$(RC_EXIT)" -DRC_DECLARE="$(RC_DECLARE)"
-+endif
- 
- INCS += -I$(TOP) -I$(ATH_HAL) -I$(HAL) -I$(WLAN)
- 
-@@ -72,13 +88,8 @@ install:
- 	test -d $(DESTDIR)/$(KMODPATH) || mkdir -p $(DESTDIR)/$(KMODPATH)
- 	install -m 0644 ath_$(BUSNAME).$(KMODSUF) $(DESTDIR)/$(KMODPATH)
- 
--clean:
--	rm -f *~ *.o *.ko *.mod.c .*.cmd
--	rm -f .depend .version .*.o.flags .*.o.d
--	rm -rf .tmp_versions
--
- ath_$(BUSNAME).o: $(ath_$(BUSNAME)-objs)
--	$(LD) $(LDOPTS) -o ath_$(BUSNAME).$(KMODSUF) -r $(ath_$(BUSNAME)-objs)
-+	$(LD) $(LDOPTS) -o ath_$(BUSNAME).$(KMODSUF) -r $(if $(ath_$(BUSNAME)-linkobjs),$(ath_$(BUSNAME)-linkobjs),$(ath_$(BUSNAME)-objs))
- 
- if_ath_hal.h: $(HAL)/ah.h
- 	$(TOP)/scripts/if_ath_hal_generator.pl $< $@
---- a/net80211/ieee80211_acl.c
-+++ b/net80211/ieee80211_acl.c
-@@ -281,16 +281,6 @@ acl_getpolicy(struct ieee80211vap *vap)
- 	return as->as_policy;
- }
- 
--/*
-- * Module glue.
-- */
--
--MODULE_AUTHOR("Errno Consulting, Sam Leffler");
--MODULE_DESCRIPTION("802.11 wireless support: MAC-based ACL policy");
--#ifdef MODULE_LICENSE
--MODULE_LICENSE("Dual BSD/GPL");
--#endif
--
- static const struct ieee80211_aclator mac = {
- 	.iac_name	= "mac",
- 	.iac_attach	= acl_attach,
-@@ -303,6 +293,18 @@ static const struct ieee80211_aclator ma
- 	.iac_getpolicy	= acl_getpolicy,
- };
- 
-+#include "module.h"
-+/*
-+ * Module glue.
-+ */
-+
-+MODULE_AUTHOR("Errno Consulting, Sam Leffler");
-+MODULE_DESCRIPTION("802.11 wireless support: MAC-based ACL policy");
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("Dual BSD/GPL");
-+#endif
-+
-+
- static int __init
- init_ieee80211_acl(void)
- {
---- a/net80211/ieee80211_crypto_ccmp.c
-+++ b/net80211/ieee80211_crypto_ccmp.c
-@@ -686,6 +686,8 @@ ccmp_decrypt(struct ieee80211_key *key,
- }
- #undef CCMP_DECRYPT
- 
-+#include "module.h"
-+
- /*
-  * Module glue.
-  */
---- a/net80211/ieee80211_crypto_tkip.c
-+++ b/net80211/ieee80211_crypto_tkip.c
-@@ -1046,6 +1046,8 @@ tkip_decrypt(struct tkip_ctx *ctx, struc
- 	return 1;
- }
- 
-+#include "module.h"
-+
- /*
-  * Module glue.
-  */
---- a/net80211/ieee80211_crypto_wep.c
-+++ b/net80211/ieee80211_crypto_wep.c
-@@ -497,6 +497,8 @@ wep_decrypt(struct ieee80211_key *key, s
-  * Module glue.
-  */
- 
-+#include "module.h"
-+
- MODULE_AUTHOR("Errno Consulting, Sam Leffler");
- MODULE_DESCRIPTION("802.11 wireless support: WEP cipher");
- #ifdef MODULE_LICENSE
---- a/net80211/ieee80211_linux.c
-+++ b/net80211/ieee80211_linux.c
-@@ -1015,6 +1015,10 @@ static struct notifier_block ieee80211_e
- static char *version = RELEASE_VERSION;
- static char *dev_info = "wlan";
- 
-+extern	void ieee80211_auth_setup(void);
-+
-+#include "module.h"
-+
- MODULE_AUTHOR("Errno Consulting, Sam Leffler");
- MODULE_DESCRIPTION("802.11 wireless LAN protocol support");
- #ifdef MODULE_VERSION
-@@ -1024,8 +1028,6 @@ MODULE_VERSION(RELEASE_VERSION);
- MODULE_LICENSE("Dual BSD/GPL");
- #endif
- 
--extern	void ieee80211_auth_setup(void);
--
- static int __init
- init_wlan(void)
- {
---- a/net80211/ieee80211_scan_ap.c
-+++ b/net80211/ieee80211_scan_ap.c
-@@ -763,15 +763,6 @@ action_tasklet(IEEE80211_TQUEUE_ARG data
- 	(*ss->ss_ops->scan_default)(vap, &as->as_selbss);
- }
- 
--/*
-- * Module glue.
-- */
--MODULE_AUTHOR("Errno Consulting, Sam Leffler");
--MODULE_DESCRIPTION("802.11 wireless support: default ap scanner");
--#ifdef MODULE_LICENSE
--MODULE_LICENSE("Dual BSD/GPL");
--#endif
--
- static const struct ieee80211_scanner ap_default = {
- 	.scan_name		= "default",
- 	.scan_attach		= ap_attach,
-@@ -789,6 +780,16 @@ static const struct ieee80211_scanner ap
- 	.scan_default		= ap_default_action,
- };
- 
-+#include "module.h"
-+
-+/*
-+ * Module glue.
-+ */
-+MODULE_AUTHOR("Errno Consulting, Sam Leffler");
-+MODULE_DESCRIPTION("802.11 wireless support: default ap scanner");
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("Dual BSD/GPL");
-+#endif
- 
- static int __init
- init_scanner_ap(void)
---- a/net80211/ieee80211_scan_sta.c
-+++ b/net80211/ieee80211_scan_sta.c
-@@ -1208,6 +1208,8 @@ action_tasklet(IEEE80211_TQUEUE_ARG data
- 		ieee80211_start_scan(vap, ss->ss_flags, ss->ss_duration, ss->ss_nssid, ss->ss_ssid);
- }
- 
-+#include "module.h"
-+
- /*
-  * Module glue.
-  */
-@@ -1217,6 +1219,7 @@ MODULE_DESCRIPTION("802.11 wireless supp
- MODULE_LICENSE("Dual BSD/GPL");
- #endif
- 
-+
- static int __init
- init_scanner_sta(void)
- {
---- a/net80211/ieee80211_xauth.c
-+++ b/net80211/ieee80211_xauth.c
-@@ -65,15 +65,6 @@
- #include <net80211/ieee80211_var.h>
- 
- /*
-- * Module glue.
-- */
--MODULE_AUTHOR("Errno Consulting, Sam Leffler");
--MODULE_DESCRIPTION("802.11 wireless support: external (user mode) authenticator");
--#ifdef MODULE_LICENSE
--MODULE_LICENSE("Dual BSD/GPL");
--#endif
--
--/*
-  * One module handles everything for now.  May want
-  * to split things up for embedded applications.
-  */
-@@ -85,6 +76,18 @@ static const struct ieee80211_authentica
- 	.ia_node_leave	= NULL,
- };
- 
-+#include "module.h"
-+
-+/*
-+ * Module glue.
-+ */
-+MODULE_AUTHOR("Errno Consulting, Sam Leffler");
-+MODULE_DESCRIPTION("802.11 wireless support: external (user mode) authenticator");
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("Dual BSD/GPL");
-+#endif
-+
-+
- static int __init
- init_ieee80211_xauth(void)
- {
---- a/net80211/Makefile
-+++ b/net80211/Makefile
-@@ -40,7 +40,11 @@
- # Makefile for the 802.11 WLAN modules.
- #
- obj := $(firstword $(obj) $(SUBDIRS) .)
--TOP = $(obj)/..
-+
-+include $(TOP)/Makefile.inc
-+
-+ifeq ($(SINGLE_MODULE),)
-+
- #
- # There is one authenticator mechanism: an in-kernel implementation
- # (wlan_xauth). 
-@@ -59,29 +63,8 @@ MOD_INSTALL	:= wlan.o wlan_wep.o wlan_tk
- 
- obj-m		+= $(MOD_INSTALL)
- 
--wlan-objs	:= if_media.o \
--		   ieee80211_skb.o \
--		   ieee80211.o ieee80211_beacon.o ieee80211_crypto.o \
--		   ieee80211_crypto_none.o ieee80211_input.o ieee80211_node.o \
--		   ieee80211_output.o ieee80211_power.o ieee80211_proto.o \
--		   ieee80211_scan.o ieee80211_wireless.o ieee80211_linux.o \
--		   ieee80211_monitor.o ieee80211_rate.o
--wlan_wep-objs	:= ieee80211_crypto_wep.o
--wlan_tkip-objs	:= ieee80211_crypto_tkip.o
--wlan_ccmp-objs	:= ieee80211_crypto_ccmp.o
--wlan_acl-objs	:= ieee80211_acl.o
--wlan_xauth-objs	:= ieee80211_xauth.o
--wlan_scan_sta-objs :=ieee80211_scan_sta.o
--wlan_scan_ap-objs := ieee80211_scan_ap.o
--
--include $(TOP)/Makefile.inc
--
- INCS += -I$(TOP) -I$(ATH_HAL) -I$(HAL)
- 
--EXTRA_CFLAGS+=$(INCS) $(COPTS) -DOPT_AH_H=\"public/$(TARGET).opt_ah.h\"
--
---include $(TOPDIR)/Rules.make
--
- all:
- 	$(MAKE) -C $(KERNELPATH) SUBDIRS=$(shell pwd) modules
- 
-@@ -108,8 +91,28 @@ install:
- 		f=`basename $$i .o`; \
- 		install -m 0644  $$f.$(KMODSUF) $(DESTDIR)/$(KMODPATH); \
- 	done
-+else
-+all:
-+endif
-+
-+wlan-objs	:= if_media.o \
-+		   ieee80211_skb.o \
-+		   ieee80211.o ieee80211_beacon.o ieee80211_crypto.o \
-+		   ieee80211_crypto_none.o ieee80211_input.o ieee80211_node.o \
-+		   ieee80211_output.o ieee80211_power.o ieee80211_proto.o \
-+		   ieee80211_scan.o ieee80211_wireless.o ieee80211_linux.o \
-+		   ieee80211_monitor.o ieee80211_rate.o
-+wlan_wep-objs	:= ieee80211_crypto_wep.o
-+wlan_tkip-objs	:= ieee80211_crypto_tkip.o
-+wlan_ccmp-objs	:= ieee80211_crypto_ccmp.o
-+wlan_acl-objs	:= ieee80211_acl.o
-+wlan_xauth-objs	:= ieee80211_xauth.o
-+wlan_scan_sta-objs :=ieee80211_scan_sta.o
-+wlan_scan_ap-objs := ieee80211_scan_ap.o
-+
-+
-+EXTRA_CFLAGS+=$(INCS) $(COPTS) -DOPT_AH_H=\"public/$(TARGET).opt_ah.h\"
-+
-+-include $(TOPDIR)/Rules.make
-+
- 
--clean:
--	-rm -f *~ *.o *.ko *.mod.c
--	-rm -f .depend .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
--	-rm -rf .tmp_versions
---- /dev/null
-+++ b/net80211/module.h
-@@ -0,0 +1,19 @@
-+#ifdef SINGLE_MODULE
-+
-+#undef static
-+#define static
-+#undef module_init
-+#undef module_exit
-+#define module_init(...)
-+#define module_exit(...)
-+
-+#undef MODULE_AUTHOR
-+#undef MODULE_LICENSE
-+#undef MODULE_VERSION
-+#undef MODULE_DESCRIPTION
-+#define MODULE_AUTHOR(...)
-+#define MODULE_LICENSE(...)
-+#define MODULE_VERSION(...)
-+#define MODULE_DESCRIPTION(...)
-+
-+#endif
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -13780,3 +13780,5 @@ cleanup_ath_buf(struct ath_softc *sc, st
- 	return bf;
- }
- 
-+
-+
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -42,6 +42,7 @@
- #include <linux/config.h>
- #endif
- #include <linux/version.h>
-+#include <linux/init.h>
- #include <linux/module.h>
- #include <linux/skbuff.h>
- #include <linux/netdevice.h>
-@@ -2015,3 +2016,65 @@ ieee80211_build_sc_ie(struct ieee80211co
- int ath_debug_global = 0;
- EXPORT_SYMBOL(ath_debug_global);
- 
-+#ifdef SINGLE_MODULE
-+typedef void (*initfunc)(void);
-+
-+extern void init_ieee80211_acl(void);
-+extern void init_crypto_ccmp(void);
-+extern void init_crypto_tkip(void);
-+extern void init_crypto_wep(void);
-+extern void init_wlan(void);
-+extern void init_scanner_ap(void);
-+extern void init_scanner_sta(void);
-+extern void init_ieee80211_xauth(void);
-+
-+extern void exit_ieee80211_acl(void);
-+extern void exit_crypto_ccmp(void);
-+extern void exit_crypto_tkip(void);
-+extern void exit_crypto_wep(void);
-+extern void exit_wlan(void);
-+extern void exit_scanner_ap(void);
-+extern void exit_scanner_sta(void);
-+extern void exit_ieee80211_xauth(void);
-+
-+static __initdata initfunc net80211_init[] = {
-+	init_wlan,
-+	init_ieee80211_acl,
-+	init_crypto_ccmp,
-+	init_crypto_tkip,
-+	init_crypto_wep,
-+	init_ieee80211_xauth,
-+	init_scanner_ap,
-+	init_scanner_sta,
-+};
-+
-+static __exitdata initfunc net80211_exit[] = {
-+	exit_crypto_ccmp,
-+	exit_crypto_tkip,
-+	exit_crypto_wep,
-+	exit_scanner_ap,
-+	exit_scanner_sta,
-+	exit_ieee80211_xauth,
-+	exit_ieee80211_acl,
-+	exit_wlan,
-+};
-+
-+void net80211_init_module(void)
-+{
-+	int i;
-+	for (i = 0; i < sizeof(net80211_init)/sizeof(net80211_init[0]); i++) {
-+		if (net80211_init[i])
-+			net80211_init[i]();
-+	}
-+}
-+
-+void net80211_exit_module(void)
-+{
-+	int i;
-+	for (i = 0; i < sizeof(net80211_exit)/sizeof(net80211_exit[0]); i++) {
-+		if (net80211_exit[i])
-+			net80211_exit[i]();
-+	}
-+}
-+
-+#endif
---- a/ath/if_ath_ahb.c
-+++ b/ath/if_ath_ahb.c
-@@ -447,10 +447,18 @@ MODULE_SUPPORTED_DEVICE("Atheros WLAN ca
- MODULE_LICENSE("Dual BSD/GPL");
- #endif
- 
-+#ifdef SINGLE_MODULE
-+RC_DECLARE
-+#endif
-+
- static int __init
- init_ath_ahb(void)
- {
- 	printk(KERN_INFO "%s: %s\n", dev_info, version);
-+#ifdef SINGLE_MODULE
-+	net80211_init_module();
-+	RC_INIT
-+#endif
- 	platform_driver_register(&ahb_wmac_driver);
- 	ath_sysctl_register();
- 
-@@ -463,6 +471,10 @@ exit_ath_ahb(void)
- {
- 	ath_sysctl_unregister();
- 	platform_driver_unregister(&ahb_wmac_driver);
-+#ifdef SINGLE_MODULE
-+	RC_EXIT
-+	net80211_exit_module();
-+#endif
- 	printk(KERN_INFO "%s: driver unloaded\n", dev_info);
- }
- module_exit(exit_ath_ahb);
---- a/ath/if_ath_pci.c
-+++ b/ath/if_ath_pci.c
-@@ -415,11 +415,19 @@ MODULE_SUPPORTED_DEVICE("Atheros WLAN ca
- MODULE_LICENSE("Dual BSD/GPL");
- #endif
- 
-+#ifdef SINGLE_MODULE
-+RC_DECLARE
-+#endif
-+
- static int __init
- init_ath_pci(void)
- {
- 	printk(KERN_INFO "%s: %s\n", dev_info, version);
- 
-+#ifdef SINGLE_MODULE
-+	net80211_init_module();
-+	RC_INIT
-+#endif
- 	if (pci_register_driver(&ath_pci_driver) < 0) {
- 		printk(KERN_ERR "%s: No devices found, driver not installed.\n", dev_info);
- 		return (-ENODEV);
-@@ -434,6 +442,10 @@ exit_ath_pci(void)
- {
- 	ath_sysctl_unregister();
- 	pci_unregister_driver(&ath_pci_driver);
-+#ifdef SINGLE_MODULE
-+	RC_EXIT
-+	net80211_exit_module();
-+#endif
- 
- 	printk(KERN_INFO "%s: driver unloaded\n", dev_info);
- }
---- a/ath_rate/minstrel/Makefile
-+++ b/ath_rate/minstrel/Makefile
-@@ -39,9 +39,7 @@
- # Makefile for the Atheros Rate Control Support.
- #
- obj := $(firstword $(obj) $(SUBDIRS) .)
--TOP = $(obj)/../..
- 
--obj-m		+= ath_rate_minstrel.o
- ath_rate_minstrel-objs	:= minstrel.o
- 
- include $(TOP)/Makefile.inc
-@@ -50,6 +48,10 @@ INCS += -I$(TOP) -I$(ATH) -I$(ATH_HAL) -
- 
- EXTRA_CFLAGS+= $(INCS) $(COPTS) -DOPT_AH_H=\"public/$(TARGET).opt_ah.h\"
- 
-+ifeq ($(SINGLE_MODULE),)
-+
-+obj-m		+= ath_rate_minstrel.o
-+
- -include $(TOPDIR)/Rules.make
- 
- all:
-@@ -59,10 +61,9 @@ install:
- 	test -d $(DESTDIR)/$(KMODPATH) || mkdir -p $(DESTDIR)/$(KMODPATH)
- 	install -m 0644 ath_rate_minstrel.$(KMODSUF) $(DESTDIR)/$(KMODPATH)
- 
--clean:
--	-rm -f *~ *.o *.ko *.mod.c
--	-rm -f .depend .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
--	-rm -rf .tmp_versions
--
- ath_rate_minstrel.o: $(ath_rate_minstrel-objs)
- 	$(LD) $(LDOPTS) -o ath_rate_minstrel.$(KMODSUF) -r $(ath_rate_minstrel-objs)
-+else
-+all:
-+install:
-+endif
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -945,6 +945,8 @@ static struct ieee80211_rate_ops ath_rat
- 		.dynamic_proc_register = ath_rate_dynamic_proc_register,
- };
- 
-+#include <net80211/module.h>
-+
- MODULE_AUTHOR("John Bicket/Derek Smithies");
- MODULE_DESCRIPTION("Minstrel Rate bit-rate selection algorithm for Atheros devices");
- #ifdef MODULE_VERSION
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -47,6 +47,7 @@
- #include <net80211/ieee80211_power.h>
- #include <net80211/ieee80211_proto.h>
- #include <net80211/ieee80211_scan.h>
-+#include "symbol.h"
- 
- /* NB: 
-  * - Atheros chips use 6 bits when power is specified in whole dBm units, with 
-@@ -740,6 +741,8 @@ void ieee80211_dfs_action(struct ieee802
- void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *);
- void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs);
- int ieee80211_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-+void net80211_init_module(void);
-+void net80211_exit_module(void);
- 
- /*
-  * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers.
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -521,7 +521,10 @@ extern struct sk_buff * ieee80211_getmgt
- #define	IF_DRAIN(_q)		skb_queue_drain(_q)
- extern	void skb_queue_drain(struct sk_buff_head *q);
- 
--#ifndef __MOD_INC_USE_COUNT
-+#ifdef SINGLE_MODULE
-+#define _MOD_DEC_USE(_m) do {} while(0)
-+#define _MOD_INC_USE(_m, _err) do {} while(0)
-+#elif !defined(__MOD_INC_USE_COUNT)
- #define	_MOD_INC_USE(_m, _err)						\
- 	if (!try_module_get(_m)) {					\
- 		printk(KERN_WARNING "%s: try_module_get failed\n",	\
---- a/ath_rate/sample/Makefile
-+++ b/ath_rate/sample/Makefile
-@@ -39,9 +39,7 @@
- # Makefile for the Atheros Rate Control Support.
- #
- obj := $(firstword $(obj) $(SUBDIRS) .)
--TOP = $(obj)/../..
- 
--obj-m		+= ath_rate_sample.o
- ath_rate_sample-objs	:= sample.o
- 
- include $(TOP)/Makefile.inc
-@@ -50,6 +48,9 @@ INCS += -I$(TOP) -I$(ATH) -I$(ATH_HAL) -
- 
- EXTRA_CFLAGS+= $(INCS) $(COPTS) -DOPT_AH_H=\"public/$(TARGET).opt_ah.h\"
- 
-+ifeq ($(SINGLE_MODULE),)
-+obj-m		+= ath_rate_sample.o
-+
- -include $(TOPDIR)/Rules.make
- 
- all:
-@@ -59,10 +60,9 @@ install:
- 	test -d $(DESTDIR)/$(KMODPATH) || mkdir -p $(DESTDIR)/$(KMODPATH)
- 	install -m 0644 ath_rate_sample.$(KMODSUF) $(DESTDIR)/$(KMODPATH)
- 
--clean:
--	-rm -f *~ *.o *.ko *.mod.c
--	-rm -f .depend .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
--	-rm -rf .tmp_versions
--
- ath_rate_sample.o: $(ath_rate_sample-objs)
- 	$(LD) $(LDOPTS) -o ath_rate_sample.$(KMODSUF) -r $(ath_rate_sample-objs)
-+else
-+all:
-+install:
-+endif
---- a/Makefile
-+++ b/Makefile
-@@ -41,7 +41,7 @@
- #
- 
- obj := $(firstword $(obj) $(SUBDIRS) .)
--TOP = $(obj)
-+export TOP:=$(if $(wildcard $(firstword $(SUBDIRS))/Makefile.inc),$(firstword $(SUBDIRS)),$(CURDIR))
- 
- ifneq (svnversion.h,$(MAKECMDGOALS))
- include $(TOP)/Makefile.inc
-@@ -54,7 +54,7 @@ all: modules tools
- modules: configcheck svnversion.h
- ifdef LINUX24
- 	for i in $(obj-y); do \
--		$(MAKE) -C $$i || exit 1; \
-+		$(MAKE) -C $$i TOP="$(TOP)" || exit 1; \
- 	done
- else
- 	$(MAKE) -C $(KERNELPATH) SUBDIRS=$(shell pwd) modules
-@@ -89,7 +89,7 @@ install-modules: modules
- 	sh scripts/find-madwifi-modules.sh -r $(KERNELRELEASE) $(DESTDIR)
- 
- 	for i in $(obj-y); do \
--		$(MAKE) -C $$i install || exit 1; \
-+		$(MAKE) -C $$i install TOP="$(TOP)" || exit 1; \
- 	done
- ifeq ($(DESTDIR),)
- 	(export KMODPATH=$(KMODPATH); /sbin/depmod -ae $(KERNELRELEASE))
-@@ -114,12 +114,21 @@ reinstall-tools: uninstall-tools install
- reinstall-modules: uninstall-modules install-modules
- 
- clean:
--	for i in $(obj-y); do \
--		$(MAKE) -C $$i clean; \
--	done
--	-$(MAKE) -C $(TOOLS) clean
--	rm -rf .tmp_versions
-+	-find $(obj-y) -name '*~' \
-+		-or -name '*.o' \
-+		-or -name '*.o.d' \
-+		-or -name '*.o.cmd' \
-+		-or -name '*.o.flags' \
-+		-or -name '*.ko' \
-+		-or -name '*.ko.cmd' \
-+		-or -name '*.mod.c' \
-+		-or -name '.depend' \
-+		-or -name '.version' \
-+		-or -name '.symvers' | \
-+		xargs -r rm -f
- 	rm -f *.symvers svnversion.h
-+	rm -rf .tmp_versions
-+	make -C tools clean
- 
- info:
- 	@echo "The following settings will be used for compilation:"
-@@ -135,18 +144,6 @@ info:
- 	@echo "KMODPATH     : $(KMODPATH)"
- 	@echo "KMODSUF      : $(KMODSUF)"
- 
--sanitycheck:
--	@echo -n "Checking requirements... "
--	
--	@# check if specified rate control is available
--	@if [ ! -d $(ATH_RATE) ]; then \
--	    echo "FAILED"; \
--	    echo "Selected rate control $(ATH_RATE) not available."; \
--	    exit 1; \
--	fi
--	
--	@echo "ok."
--
- .PHONY: release
- release:
- 	sh scripts/make-release.bash
-@@ -155,7 +152,7 @@ release:
- unload:
- 	bash scripts/madwifi-unload
- 
--configcheck: sanitycheck
-+configcheck:
- 	@echo -n "Checking kernel configuration... "
- 	
- 	@# check version of kernel
---- a/Makefile.inc
-+++ b/Makefile.inc
-@@ -68,6 +68,9 @@ endif
- export KERNELPATH
- endif
- 
-+# build net80211 and ath_ahb/ath_pci into a single module
-+export SINGLE_MODULE=1
-+
- # KERNELRELEASE is the target kernel's version.  It's always taken from
- # the kernel build tree.  Kernel Makefile doesn't always know the exact
- # kernel version (especially for vendor stock kernels), so we get it
-@@ -100,6 +103,7 @@ export ARCH
- include $(TOP)/ath_hal/ah_target.inc
- export TARGET
- COPTS += -DTARGET='"$(TARGET)"'
-+COPTS += -DCONFIG_ATHEROS_RATE_DEFAULT='"$(firstword $(ATH_RATE))"'
- 
- # KMODPATH nominates the directory where the modules will be
- # installed to
-@@ -141,7 +145,7 @@ ATH=	$(TOP)/ath
- #
- # Path to the rate control algorithms.
- #
--ATH_RATE=	$(TOP)/ath_rate
-+ATH_RATE=	minstrel
- #
- # Path to the userspace utilities. 
- # 
---- a/ath_rate/sample/sample.c
-+++ b/ath_rate/sample/sample.c
-@@ -991,6 +991,8 @@ static struct ieee80211_rate_ops ath_rat
- 	.dynamic_proc_register = ath_rate_dynamic_proc_register,
- };
- 
-+#include <net80211/module.h>
-+
- MODULE_AUTHOR("John Bicket");
- MODULE_DESCRIPTION("SampleRate bit-rate selection algorithm for Atheros devices");
- #ifdef MODULE_VERSION
-@@ -1000,18 +1002,17 @@ MODULE_VERSION(RELEASE_VERSION);
- MODULE_LICENSE("Dual BSD/GPL");
- #endif
- 
--static int __init
--init_ath_rate_sample(void)
-+static int __init ath_rate_sample_init(void)
- {
- 	printk(KERN_INFO "%s: %s\n", dev_info, version);
- 	return ieee80211_rate_register(&ath_rate_ops);
- }
--module_init(init_ath_rate_sample);
-+module_init(ath_rate_sample_init);
- 
- static void __exit
--exit_ath_rate_sample(void)
-+ath_rate_sample_exit(void)
- {
- 	ieee80211_rate_unregister(&ath_rate_ops);
- 	printk(KERN_INFO "%s: unloaded\n", dev_info);
- }
--module_exit(exit_ath_rate_sample);
-+module_exit(ath_rate_sample_exit);
---- a/net80211/if_media.h
-+++ b/net80211/if_media.h
-@@ -42,6 +42,7 @@
- #define _NET_IF_MEDIA_H_
- 
- #include <net80211/ieee80211_linux.h>
-+#include "symbol.h"
- 
- /*
-  * Prototypes and definitions for BSD/OS-compatible network interface
---- /dev/null
-+++ b/net80211/symbol.h
-@@ -0,0 +1,4 @@
-+#ifdef SINGLE_MODULE
-+#undef EXPORT_SYMBOL
-+#define EXPORT_SYMBOL(...)
-+#endif
---- a/ath_rate/Makefile
-+++ b/ath_rate/Makefile
-@@ -1,7 +1,7 @@
- obj := $(firstword $(obj) $(SUBDIRS) .)
- TOP = $(obj)/..
- 
--obj-y := amrr/ onoe/ sample/ minstrel/
-+obj-y := sample/ minstrel/
- 
- include $(TOP)/Makefile.inc
- 
diff --git a/package/madwifi/patches/447-sta_reconnect.patch b/package/madwifi/patches/447-sta_reconnect.patch
deleted file mode 100644
index 960d1b8ed8..0000000000
--- a/package/madwifi/patches/447-sta_reconnect.patch
+++ /dev/null
@@ -1,25 +0,0 @@
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -647,8 +647,11 @@ ieee80211_sta_join1(struct ieee80211_nod
- 		(vap->iv_state == IEEE80211_S_RUN) && bssid_equal(obss, selbs)); */
- 	vap->iv_bss = selbs;
- 	IEEE80211_ADDR_COPY(vap->iv_bssid, selbs->ni_bssid);
--	if (obss != NULL)
-+	if (obss != NULL) {
-+		if (obss->ni_table)
-+			ieee80211_node_leave(obss);
- 		ieee80211_unref_node(&obss);
-+	}
- 	ic->ic_bsschan = selbs->ni_chan;
- 	ic->ic_curchan = ic->ic_bsschan;
- 	ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan);
---- a/net80211/ieee80211_proto.c
-+++ b/net80211/ieee80211_proto.c
-@@ -1602,7 +1602,6 @@ __ieee80211_newstate(struct ieee80211vap
- 				IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
- 			break;
- 		case IEEE80211_S_RUN:
--			ieee80211_node_leave(ni);
- 			if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
- 				/* NB: caller specifies ASSOC/REASSOC by arg */
- 				IEEE80211_SEND_MGMT(ni, arg ?
diff --git a/package/madwifi/patches/448-beacon_handling_fixes.patch b/package/madwifi/patches/448-beacon_handling_fixes.patch
deleted file mode 100644
index 9c0f912e45..0000000000
--- a/package/madwifi/patches/448-beacon_handling_fixes.patch
+++ /dev/null
@@ -1,407 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -160,7 +160,7 @@ static int ath_check_beacon_done(struct
- static void ath_beacon_send(struct ath_softc *, int *, uint64_t hw_tsf);
- static void ath_beacon_return(struct ath_softc *, struct ath_buf *);
- static void ath_beacon_free(struct ath_softc *);
--static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *);
-+static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *, int);
- static void ath_hw_beacon_stop(struct ath_softc *sc);
- static int ath_desc_alloc(struct ath_softc *);
- static void ath_desc_free(struct ath_softc *);
-@@ -387,13 +387,11 @@ static void ath_set_timing(struct ath_so
- /* calibrate every 30 secs in steady state but check every second at first. */
- static int ath_calinterval = ATH_SHORT_CALINTERVAL;
- static int ath_xchanmode = AH_TRUE;		/* enable extended channels */
--static int ath_maxvaps = ATH_MAXVAPS_DEFAULT;   /* set default maximum vaps */
- static int bstuck_thresh = BSTUCK_THRESH;       /* Stuck beacon count required for reset */
- static char *autocreate = NULL;
- static char *ratectl = DEF_RATE_CTL;
- static int rfkill = 0;
- static int tpc = 1;
--static int maxvaps = -1;
- static int xchanmode = -1;
- #include "ath_wprobe.c"
- static int beacon_cal = 1;
-@@ -432,7 +430,6 @@ static struct notifier_block ath_event_b
- 
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
- MODULE_PARM(beacon_cal, "i");
--MODULE_PARM(maxvaps, "i");
- MODULE_PARM(xchanmode, "i");
- MODULE_PARM(rfkill, "i");
- #ifdef ATH_CAP_TPC
-@@ -444,7 +441,6 @@ MODULE_PARM(ratectl, "s");
- #else
- #include <linux/moduleparam.h>
- module_param(beacon_cal, int, 0600);
--module_param(maxvaps, int, 0600);
- module_param(xchanmode, int, 0600);
- module_param(rfkill, int, 0600);
- #ifdef ATH_CAP_TPC
-@@ -454,7 +450,6 @@ module_param(bstuck_thresh, int, 0600);
- module_param(autocreate, charp, 0600);
- module_param(ratectl, charp, 0600);
- #endif
--MODULE_PARM_DESC(maxvaps, "Maximum VAPs");
- MODULE_PARM_DESC(xchanmode, "Enable/disable extended channel mode");
- MODULE_PARM_DESC(rfkill, "Enable/disable RFKILL capability");
- #ifdef ATH_CAP_TPC
-@@ -512,7 +507,7 @@ MODULE_PARM_DESC(ieee80211_debug, "Load-
-  * and use the higher bits as the index of the VAP.
-  */
- #define ATH_SET_VAP_BSSID_MASK(bssid_mask)				\
--	((bssid_mask)[0] &= ~(((ath_maxvaps-1) << 2) | 0x02))
-+	((bssid_mask)[0] &= ~(((ATH_MAXVAPS_BCN-1) << 2) | 0x02))
- #define ATH_GET_VAP_ID(bssid)                   ((bssid)[0] >> 2)
- #define ATH_SET_VAP_BSSID(bssid, id)					\
- 		do {							\
-@@ -604,8 +599,8 @@ ath_attach(u_int16_t devid, struct net_d
- 
- 	/* Allocate space for dynamically determined maximum VAP count */
- 	sc->sc_bslot = 
--		kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
--	memset(sc->sc_bslot, 0, ath_maxvaps * sizeof(struct ieee80211vap*));
-+		kmalloc(ATH_MAXVAPS_BCN * sizeof(struct ieee80211vap*), GFP_KERNEL);
-+	memset(sc->sc_bslot, 0, ATH_MAXVAPS_BCN * sizeof(struct ieee80211vap*));
- 
- 	/*
- 	 * Cache line size is used to size and align various
-@@ -694,13 +689,6 @@ ath_attach(u_int16_t devid, struct net_d
- 	for (i = 0; i < sc->sc_keymax; i++)
- 		ath_hal_keyreset(ah, i);
- 
--	if (maxvaps != -1) {
--		ath_maxvaps = maxvaps;
--		if (ath_maxvaps < ATH_MAXVAPS_MIN)
--			ath_maxvaps = ATH_MAXVAPS_MIN;
--		else if (ath_maxvaps > ATH_MAXVAPS_MAX)
--			ath_maxvaps = ATH_MAXVAPS_MAX;
--	}
- 	if (xchanmode != -1)
- 		ath_xchanmode = xchanmode;
- 	error = ath_getchannels(dev);
-@@ -1349,12 +1337,6 @@ ath_vap_create(struct ieee80211com *ic,
- 		return NULL;
- 	}
- 
--	if (sc->sc_nvaps >= ath_maxvaps) {
--		EPRINTF(sc, "Too many virtual APs (%d already exist).\n", 
--				sc->sc_nvaps);
--		return NULL;
--	}
--
- 	dev = alloc_etherdev(sizeof(struct ath_vap) + sc->sc_rc->arc_vap_space);
- 	if (dev == NULL) {
- 		/* XXX msg */
-@@ -1424,7 +1406,7 @@ ath_vap_create(struct ieee80211com *ic,
- 		TAILQ_FOREACH(v, &ic->ic_vaps, iv_next)
- 			id_mask |= (1 << ATH_GET_VAP_ID(v->iv_myaddr));
- 
--		for (id = 0; id < ath_maxvaps; id++) {
-+		for (id = 0; id < ATH_MAXVAPS_BCN; id++) {
- 			/* get the first available slot */
- 			if ((id_mask & (1 << id)) == 0) {
- 				ATH_SET_VAP_BSSID(vap->iv_myaddr, id);
-@@ -1451,11 +1433,11 @@ ath_vap_create(struct ieee80211com *ic,
- 		/* Assign the VAP to a beacon xmit slot.  As
- 		 * above, this cannot fail to find one. */
- 		avp->av_bslot = 0;
--		for (slot = 0; slot < ath_maxvaps; slot++)
-+		for (slot = 0; slot < ATH_MAXVAPS_BCN; slot++)
- 			if (sc->sc_bslot[slot] == NULL) {
- 				/* XXX: Hack, space out slots to better
- 				 * deal with misses. */
--				if (slot + 1 < ath_maxvaps &&
-+				if (slot + 1 < ATH_MAXVAPS_BCN &&
- 				    sc->sc_bslot[slot+1] == NULL) {
- 					avp->av_bslot = slot + 1;
- 					break;
-@@ -1463,8 +1445,11 @@ ath_vap_create(struct ieee80211com *ic,
- 				avp->av_bslot = slot;
- 				/* NB: keep looking for a double slot */
- 			}
--		KASSERT(sc->sc_bslot[avp->av_bslot] == NULL,
--			("beacon slot %u not empty?", avp->av_bslot));
-+		if (sc->sc_bslot[avp->av_bslot]) {
-+			free_netdev(dev);
-+			return NULL;
-+		}
-+
- 		sc->sc_bslot[avp->av_bslot] = vap;
- 		sc->sc_nbcnvaps++;
- 
-@@ -1475,15 +1460,7 @@ ath_vap_create(struct ieee80211com *ic,
- 			 * of staggered beacons.
- 			 */
- 			/* XXX check for beacon interval too small */
--			if (ath_maxvaps > 4) {
--				DPRINTF(sc, ATH_DEBUG_BEACON, 
--						"Staggered beacons are not "
--						"possible with maxvaps set "
--						"to %d.\n", ath_maxvaps);
--				sc->sc_stagbeacons = 0;
--			} else {
--				sc->sc_stagbeacons = 1;
--			}
-+			sc->sc_stagbeacons = 1;
- 		}
- 		DPRINTF(sc, ATH_DEBUG_BEACON, "sc->sc_stagbeacons %sabled\n", 
- 				(sc->sc_stagbeacons ? "en" : "dis"));
-@@ -1553,7 +1530,7 @@ ath_vap_create(struct ieee80211com *ic,
- 		if (ath_startrecv(sc) != 0)	/* restart recv */
- 			EPRINTF(sc, "Unable to start receive logic.\n");
- 		if (sc->sc_beacons)
--			ath_beacon_config(sc, NULL);	/* restart beacons */
-+			ath_beacon_config(sc, NULL, 0);	/* restart beacons */
- 		ath_hal_intrset(ah, sc->sc_imask);
- 	}
- 
-@@ -1681,7 +1658,7 @@ ath_vap_delete(struct ieee80211vap *vap)
- 		if (ath_startrecv(sc) != 0)		/* restart recv. */
- 			EPRINTF(sc, "Unable to start receive logic.\n");
- 		if (sc->sc_beacons)
--			ath_beacon_config(sc, NULL);	/* restart beacons */
-+			ath_beacon_config(sc, NULL, 0);	/* restart beacons */
- 		ath_hal_intrset(ah, sc->sc_imask);
- 	}
- }
-@@ -3066,7 +3043,7 @@ ath_reset(struct net_device *dev)
- 	 */
- 	ath_chan_change(sc, c);
- 	if (sc->sc_beacons)
--		ath_beacon_config(sc, NULL);	/* restart beacons */
-+		ath_beacon_config(sc, NULL, 1);	/* restart beacons */
- 	ath_hal_intrset(ah, sc->sc_imask);
- 	ath_set_ack_bitrate(sc, sc->sc_ackrate);
- 	netif_wake_queue(dev);		/* restart xmit */
-@@ -4763,7 +4740,7 @@ ath_check_beacon_done(struct ath_softc *
- 	/*
- 	 * check if the last beacon went out with the mode change flag set.
- 	 */
--	for (slot = 0; slot < ath_maxvaps; slot++) {
-+	for (slot = 0; slot < ATH_MAXVAPS_BCN; slot++) {
- 		if (sc->sc_bslot[slot]) {
- 			vap = sc->sc_bslot[slot];
- 			break;
-@@ -4968,7 +4945,7 @@ ath_beacon_alloc_internal(struct ath_sof
- 		 * has a timestamp in one beacon interval while the
- 		 * others get a timestamp aligned to the next interval.
- 		 */
--		tuadjust = (ni->ni_intval * (ath_maxvaps - avp->av_bslot)) / ath_maxvaps;
-+		tuadjust = (ni->ni_intval * (ATH_MAXVAPS_BCN - avp->av_bslot)) / ATH_MAXVAPS_BCN;
- 		tsfadjust = cpu_to_le64(tuadjust << 10);	/* TU->TSF */
- 
- 		DPRINTF(sc, ATH_DEBUG_BEACON,
-@@ -5361,8 +5338,8 @@ ath_beacon_send(struct ath_softc *sc, in
- 		u_int32_t tsftu;
- 
- 		tsftu = hw_tsf >> 10; /* NB: 64 -> 32: See note far above. */
--		slot = ((tsftu % ic->ic_lintval) * ath_maxvaps) / ic->ic_lintval;
--		vap = sc->sc_bslot[(slot + 1) % ath_maxvaps];
-+		slot = ((tsftu % ic->ic_lintval) * ATH_MAXVAPS_BCN) / ic->ic_lintval;
-+		vap = sc->sc_bslot[(slot + 1) % ATH_MAXVAPS_BCN];
- 		DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
- 			"Slot %d [tsf %llu tsftu %llu intval %u] vap %p\n",
- 			slot, (unsigned long long)hw_tsf, 
-@@ -5377,7 +5354,7 @@ ath_beacon_send(struct ath_softc *sc, in
- 		u_int32_t *bflink = NULL;
- 
- 		/* XXX: rotate/randomize order? */
--		for (slot = 0; slot < ath_maxvaps; slot++) {
-+		for (slot = 0; slot < ATH_MAXVAPS_BCN; slot++) {
- 			if ((vap = sc->sc_bslot[slot]) != NULL) {
- 				if ((bf = ath_beacon_generate(
- 						sc, vap, 
-@@ -5418,7 +5395,7 @@ ath_beacon_send(struct ath_softc *sc, in
- 	 *     again.  If we miss a beacon for that slot then we'll be
- 	 *     slow to transition but we'll be sure at least one beacon
- 	 *     interval has passed.  When bursting slot is always left
--	 *     set to ath_maxvaps so this check is a no-op.
-+	 *     set to ATH_MAXVAPS_BCN so this check is a no-op.
- 	 */
- 	/* XXX locking */
- 	if (sc->sc_updateslot == UPDATE) {
-@@ -5526,7 +5503,7 @@ ath_beacon_free(struct ath_softc *sc)
-  * (2^(32 + 10 - 1) - 1)us is a really long time.
-  */
- static void
--ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
-+ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap, int reset)
- {
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ath_hal *ah = sc->sc_ah;
-@@ -5553,7 +5530,7 @@ ath_beacon_config(struct ath_softc *sc,
- 	/* We should reset hw TSF only once, so we increment
- 	 * ni_tstamp.tsf to avoid resetting the hw TSF multiple
- 	 * times */
--	if (tsf == 0) {
-+	if (tsf == 0 || reset) {
- 		reset_tsf = 1;
- 		ni->ni_tstamp.tsf = cpu_to_le64(1);
- 	}
-@@ -5567,7 +5544,7 @@ ath_beacon_config(struct ath_softc *sc,
- 		/* NB: the beacon interval is kept internally in TUs */
- 		intval = ic->ic_lintval & HAL_BEACON_PERIOD;
- 		if (sc->sc_stagbeacons)
--			intval /= ath_maxvaps;	/* for staggered beacons */
-+			intval /= ATH_MAXVAPS_BCN;	/* for staggered beacons */
- 		if ((sc->sc_nostabeacons) &&
- 		    (vap->iv_opmode == IEEE80211_M_HOSTAP))
- 			reset_tsf = 1;
-@@ -5583,31 +5560,24 @@ ath_beacon_config(struct ath_softc *sc,
- 		 * time */
- 		nexttbtt = intval;
- 	} else if (intval) {	/* NB: can be 0 for monitor mode */
--		if (tsf == 1) {
--			/* We have not received any beacons or probe
--			 * responses. Since a beacon should be sent
--			 * every 'intval' ms, we compute the next
--			 * beacon timestamp using the hardware TSF. We
--			 * ensure that it is at least FUDGE TUs ahead
--			 * of the current TSF. Otherwise, we use the
--			 * next beacon timestamp again */
-- 			nexttbtt = roundup(hw_tsftu + FUDGE, intval);
--		} 
--		else if (ic->ic_opmode == IEEE80211_M_IBSS) {
--			if (tsf > hw_tsf) {
--				/* We received a beacon, but the HW TSF has
--				 * not been updated (otherwise hw_tsf > tsf)
--				 * We cannot use the hardware TSF, so we
--				 * wait to synchronize beacons again. */
--				sc->sc_syncbeacon = 1;
--				goto ath_beacon_config_debug;
--			} else {
--				/* Normal case: we received a beacon to which
--				 * we have synchronized. Make sure that nexttbtt
--				 * is at least FUDGE TU ahead of hw_tsf */
--				nexttbtt = tsftu + roundup(hw_tsftu + FUDGE - 
--						tsftu, intval);
--			}
-+		if ((tsf > hw_tsf) && (ic->ic_opmode == IEEE80211_M_IBSS)) {
-+			/* We received a beacon, but the HW TSF has
-+			 * not been updated (otherwise hw_tsf > tsf)
-+			 * We cannot use the hardware TSF, so we
-+			 * wait to synchronize beacons again. */
-+			sc->sc_syncbeacon = 1;
-+			goto ath_beacon_config_debug;
-+		} else if ((tsftu + FUDGE) > hw_tsftu) {
-+			if (tsftu > hw_tsftu + 2 * intval)
-+				nexttbtt = roundup(hw_tsftu + FUDGE, intval);
-+			else
-+				nexttbtt = tsftu;
-+		} else {
-+			/* Normal case: we received a beacon to which
-+			 * we have synchronized. Make sure that nexttbtt
-+			 * is at least FUDGE TU ahead of hw_tsf */
-+			nexttbtt = tsftu + roundup(hw_tsftu + FUDGE -
-+					tsftu, intval);
- 		}
- 	}
- 
-@@ -5730,9 +5700,6 @@ ath_beacon_config(struct ath_softc *sc,
- 		ath_beacon_dturbo_config(vap, intval &
- 				~(HAL_BEACON_RESET_TSF | HAL_BEACON_ENA));
- #endif
--		if ((nexttbtt & HAL_BEACON_PERIOD) - (ath_hal_gettsf32(ah) >> 10)
--				<= ath_hal_sw_beacon_response_time)
--			nexttbtt += intval;
- 		sc->sc_nexttbtt = nexttbtt;
- 
- 		/* stop beacons before reconfiguring the timers to avoid race
-@@ -5889,7 +5856,7 @@ ath_desc_alloc(struct ath_softc *sc)
- 
- 	/* XXX allocate beacon state together with VAP */
- 	error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
--			"beacon", ath_maxvaps, 1);
-+			"beacon", ATH_MAXVAPS_BCN, 1);
- 	if (error != 0) {
- 		ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf,
- 			BUS_DMA_TODEVICE);
-@@ -6680,7 +6647,7 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 			/* Resync beacon timers using the tsf of the
- 			 * beacon frame we just received. */
- 			vap->iv_flags_ext &= ~IEEE80211_FEXT_APPIE_UPDATE;
--			ath_beacon_config(sc, vap);
-+			ath_beacon_config(sc, vap, 0);
- 			DPRINTF(sc, ATH_DEBUG_BEACON, 
- 				"Updated beacon timers\n");
- 		}
-@@ -9359,7 +9326,7 @@ ath_chan_set(struct ath_softc *sc, struc
- 		 * HW seems to turn off beacons during turbo mode switch.
- 		 */
- 		if (sc->sc_beacons && !sc->sc_dfs_cac)
--			ath_beacon_config(sc, NULL);
-+			ath_beacon_config(sc, NULL, 0);
- 		/*
- 		 * Re-enable interrupts.
- 		 */
-@@ -9813,7 +9780,7 @@ ath_newstate(struct ieee80211vap *vap, e
- 					ATH_DEBUG_BEACON_PROC, 
- 				"Beacons reconfigured by %p[%s]!\n",
- 				vap, vap->iv_nickname);
--			ath_beacon_config(sc, vap);
-+			ath_beacon_config(sc, vap, 1);
- 			sc->sc_beacons = 1;
- 		}
- 	} else {
-@@ -9948,9 +9915,6 @@ ath_dfs_cac_completed(unsigned long data
- 		}
- 		netif_wake_queue(dev);
- 		ath_reset(dev);
--		if (sc->sc_beacons) {
--			ath_beacon_config(sc, NULL);
--		}
- 		dev->watchdog_timeo = 5 * HZ; /* restore normal timeout */
- 	} else {
- 		do_gettimeofday(&tv);
-@@ -11473,9 +11437,6 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 		case ATH_OUTDOOR:
- 			val = ic->ic_country_outdoor;
- 			break;
--		case ATH_MAXVAPS:
--			val = ath_maxvaps;
--			break;
- 		case ATH_REGDOMAIN:
- 			ath_hal_getregdomain(ah, &val);
- 			break;
-@@ -11606,12 +11567,6 @@ static const ctl_table ath_sysctl_templa
- 	  .extra2	= (void *)ATH_OUTDOOR,
- 	},
- 	{ .ctl_name	= CTL_AUTO,
--	  .procname	= "maxvaps",
--	  .mode		= 0444,
--	  .proc_handler	= ath_sysctl_halparam,
--	  .extra2	= (void *)ATH_MAXVAPS,
--	},
--	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "regdomain",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
-@@ -11928,13 +11883,6 @@ static ctl_table ath_static_sysctls[] =
- 	},
- #endif
- 	{ .ctl_name	= CTL_AUTO,
--	  .procname	= "maxvaps",
--	  .mode		= 0444,
--	  .data		= &ath_maxvaps,
--	  .maxlen	= sizeof(ath_maxvaps),
--	  .proc_handler	= proc_dointvec
--	},
--	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "xchanmode",
- 	  .mode		= 0444,
- 	  .data		= &ath_xchanmode,
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -211,9 +211,7 @@ static inline struct net_device *_alloc_
- #define	ATH_RXBUF	40		/* number of RX buffers */
- #define	ATH_TXBUF	200		/* number of TX buffers */
- 
--#define ATH_MAXVAPS_MIN 	2	/* minimum number of beacon buffers */
--#define ATH_MAXVAPS_MAX 	64	/* maximum number of beacon buffers */
--#define ATH_MAXVAPS_DEFAULT 	4	/* default number of beacon buffers */
-+#define ATH_MAXVAPS_BCN		4	/* maximum number of beacon buffers */
- 
- /* free buffer threshold to restart net dev */
- #define	ATH_TXBUF_FREE_THRESHOLD  (ATH_TXBUF / 20)
diff --git a/package/madwifi/patches/449-fix_txbuf_leak.patch b/package/madwifi/patches/449-fix_txbuf_leak.patch
deleted file mode 100644
index 31f2fef3a8..0000000000
--- a/package/madwifi/patches/449-fix_txbuf_leak.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -3697,6 +3697,7 @@ ff_bypass:
- 	 */
- 	skb = ieee80211_encap(ni, skb, &framecnt);
- 	if (skb == NULL) {
-+		STAILQ_INSERT_TAIL(&bf_head, bf, bf_list);
- 		DPRINTF(sc, ATH_DEBUG_XMIT,
- 			"Dropping; encapsulation failure\n");
- 		sc->sc_stats.ast_tx_encap++;
diff --git a/package/madwifi/patches/450-calibration.patch b/package/madwifi/patches/450-calibration.patch
deleted file mode 100644
index 87397903dc..0000000000
--- a/package/madwifi/patches/450-calibration.patch
+++ /dev/null
@@ -1,177 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -394,7 +394,6 @@ static int rfkill = 0;
- static int tpc = 1;
- static int xchanmode = -1;
- #include "ath_wprobe.c"
--static int beacon_cal = 1;
- 
- static const struct ath_hw_detect generic_hw_info = {
- 	.vendor_name = "Unknown",
-@@ -429,7 +428,6 @@ static struct notifier_block ath_event_b
- };
- 
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
--MODULE_PARM(beacon_cal, "i");
- MODULE_PARM(xchanmode, "i");
- MODULE_PARM(rfkill, "i");
- #ifdef ATH_CAP_TPC
-@@ -440,7 +438,6 @@ MODULE_PARM(autocreate, "s");
- MODULE_PARM(ratectl, "s");
- #else
- #include <linux/moduleparam.h>
--module_param(beacon_cal, int, 0600);
- module_param(xchanmode, int, 0600);
- module_param(rfkill, int, 0600);
- #ifdef ATH_CAP_TPC
-@@ -825,6 +822,7 @@ ath_attach(u_int16_t devid, struct net_d
- 		error = EIO;
- 		goto bad2;
- 	}
-+	sc->sc_cal_interval = ath_calinterval;
- 	init_timer(&sc->sc_cal_ch);
- 	sc->sc_cal_ch.function = ath_calibrate;
- 	sc->sc_cal_ch.data = (unsigned long) dev;
-@@ -2737,8 +2735,7 @@ ath_stop_locked(struct net_device *dev)
- 		}
- 		if (!sc->sc_invalid) {
- 			del_timer_sync(&sc->sc_dfs_cac_timer);
--			if (!sc->sc_beacon_cal)
--				del_timer_sync(&sc->sc_cal_ch);
-+			del_timer_sync(&sc->sc_cal_ch);
- 		}
- 		ath_draintxq(sc);
- 		if (!sc->sc_invalid) {
-@@ -2763,10 +2760,9 @@ static void ath_set_beacon_cal(struct at
- 	if (val) {
- 		del_timer_sync(&sc->sc_cal_ch);
- 	} else {
--		sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
--		add_timer(&sc->sc_cal_ch);
-+		mod_timer(&sc->sc_cal_ch, jiffies + (sc->sc_cal_interval * HZ));
- 	}
--	sc->sc_beacon_cal = !!val && beacon_cal;
-+	sc->sc_beacon_cal = !!val;
- }
- 
- /*
-@@ -3008,7 +3004,7 @@ ath_reset(struct net_device *dev)
- 	 * XXX: starting the calibration too early seems to lead to
- 	 * problems with the beacons.
- 	 */
--	sc->sc_lastcal = jiffies;
-+	sc->sc_nextcal = jiffies + msecs_to_jiffies(sc->sc_cal_interval * 1000);
- 
- 	/*
- 	 * Convert to a HAL channel description with the flags
-@@ -5430,10 +5426,9 @@ ath_beacon_send(struct ath_softc *sc, in
- 			"Invoking ath_hal_txstart with sc_bhalq: %d\n",
- 			sc->sc_bhalq);
- 		ath_hal_txstart(ah, sc->sc_bhalq);
--		if (sc->sc_beacon_cal && (jiffies > sc->sc_lastcal + (ath_calinterval * HZ))) {
--			sc->sc_cal_ch.expires = jiffies + msecs_to_jiffies(10);
--			add_timer(&sc->sc_cal_ch);
--		}
-+		if (sc->sc_beacon_cal && ((sc->sc_bmisscount == 3) ||
-+		    (jiffies > sc->sc_nextcal)))
-+			mod_timer(&sc->sc_cal_ch, jiffies + 1);
- 
- 		sc->sc_stats.ast_be_xmit++;		/* XXX per-VAP? */
- 	}
-@@ -9104,6 +9099,7 @@ ath_startrecv(struct ath_softc *sc)
- 		dev->mtu, sc->sc_cachelsz, sc->sc_rxbufsize);
- 
- 	sc->sc_rxlink = NULL;
-+	ath_set_beacon_cal(sc, IEEE80211_IS_MODE_BEACON(sc->sc_ic.ic_opmode));
- 	STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
- 		int error = ath_rxbuf_init(sc, bf);
- 		ATH_RXBUF_RESET(bf);
-@@ -9320,7 +9316,7 @@ ath_chan_set(struct ath_softc *sc, struc
- 				jiffies + (sc->sc_dfs_cac_period * HZ));
- 
- 			/* This is a good time to start a calibration */
--			ath_set_beacon_cal(sc, 1);
-+			mod_timer(&sc->sc_cal_ch, jiffies + 1);
- 		}
- 		/*
- 		 * re configure beacons when it is a turbo mode switch.
-@@ -9414,25 +9410,23 @@ ath_calibrate(unsigned long arg)
- 	if (isIQdone == AH_TRUE) {
- 		/* Unless user has overridden calibration interval,
- 		 * upgrade to less frequent calibration */
--		if (ath_calinterval == ATH_SHORT_CALINTERVAL)
--			ath_calinterval = ATH_LONG_CALINTERVAL;
-+		if (sc->sc_cal_interval == ATH_SHORT_CALINTERVAL)
-+			sc->sc_cal_interval = ATH_LONG_CALINTERVAL;
- 	}
- 	else {
- 		/* Unless user has overridden calibration interval,
- 		 * downgrade to more frequent calibration */
--		if (ath_calinterval == ATH_LONG_CALINTERVAL)
--			ath_calinterval = ATH_SHORT_CALINTERVAL;
-+		if (sc->sc_cal_interval == ATH_LONG_CALINTERVAL)
-+			sc->sc_cal_interval = ATH_SHORT_CALINTERVAL;
- 	}
- 
- 	DPRINTF(sc, ATH_DEBUG_CALIBRATE, "Channel %u/%x -- IQ %s.\n",
- 		sc->sc_curchan.channel, sc->sc_curchan.channelFlags,
- 		isIQdone ? "done" : "not done");
- 
--	sc->sc_lastcal = jiffies;
--	if (!sc->sc_beacon_cal) {
--		sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
--		add_timer(&sc->sc_cal_ch);
--	}
-+	sc->sc_nextcal = jiffies + msecs_to_jiffies(sc->sc_cal_interval * 1000);
-+	if (!sc->sc_beacon_cal)
-+		mod_timer(&sc->sc_cal_ch, sc->sc_nextcal);
- }
- 
- static void
-@@ -9540,9 +9534,6 @@ ath_newstate(struct ieee80211vap *vap, e
- 		ieee80211_state_name[vap->iv_state],
- 		ieee80211_state_name[nstate]);
- 
--	if (!sc->sc_beacon_cal)
--		del_timer(&sc->sc_cal_ch);		/* periodic calibration timer */
--
- 	ath_hal_setledstate(ah, leds[nstate]);	/* set LED */
- 	netif_stop_queue(dev);			/* before we do anything else */
- 
-@@ -9764,10 +9755,7 @@ ath_newstate(struct ieee80211vap *vap, e
- 				IEEE80211_IS_MODE_DFS_MASTER(vap->iv_opmode)) {
- 			DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_DOTH, 
- 				"VAP -> DFSWAIT_PENDING \n");
--			/* start calibration timer with a really small value 
--			 * 1/10 sec */
--			if (!sc->sc_beacon_cal)
--				mod_timer(&sc->sc_cal_ch, jiffies + (HZ/10));
-+			mod_timer(&sc->sc_cal_ch, jiffies + 1);
- 			/* wake the receiver */
- 			netif_wake_queue(dev);
- 			/* don't do the other usual stuff... */
-@@ -9809,12 +9797,6 @@ done:
- 	/* Invoke the parent method to complete the work. */
- 	error = avp->av_newstate(vap, nstate, arg);
- 
--	/* Finally, start any timers. */
--	if (nstate == IEEE80211_S_RUN && !sc->sc_beacon_cal) {
--		/* start periodic recalibration timer */
--		mod_timer(&sc->sc_cal_ch, jiffies + (ath_calinterval * HZ));
--	}
--
- #ifdef ATH_SUPERG_XR
- 	if (vap->iv_flags & IEEE80211_F_XR &&
- 		nstate == IEEE80211_S_RUN)
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -832,7 +832,8 @@ struct ath_softc {
- 
- 	struct ieee80211_channel *sc_last_chan;
- 	int sc_beacon_cal;			/* use beacon timer for calibration */
--	u_int64_t sc_lastcal;			/* last time the calibration was performed */
-+	u_int64_t sc_nextcal;			/* last time the calibration was performed */
-+	int sc_cal_interval;			/* current calibration interval */
- 	struct timer_list sc_cal_ch;		/* calibration timer */
- 	HAL_NODE_STATS sc_halstats;		/* station-mode rssi stats */
- 
diff --git a/package/madwifi/patches/451-ibss_race_fix.patch b/package/madwifi/patches/451-ibss_race_fix.patch
deleted file mode 100644
index 27e1b47dad..0000000000
--- a/package/madwifi/patches/451-ibss_race_fix.patch
+++ /dev/null
@@ -1,342 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -294,10 +294,10 @@ ieee80211_input(struct ieee80211vap * va
- 			break;
- 		case IEEE80211_M_IBSS:
- 		case IEEE80211_M_AHDEMO:
--			if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid) ||
-+			if ((!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid) ||
- 			    (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr) &&
--			     !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
--			     (subtype != IEEE80211_FC0_SUBTYPE_BEACON))) {
-+			     !IEEE80211_IS_MULTICAST(wh->i_addr1))) &&
-+			     (type == IEEE80211_FC0_TYPE_DATA)) {
- 				if (!(vap->iv_dev->flags & IFF_PROMISC)) {
- 					IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
- 						bssid, NULL, "%s", "not to bss");
-@@ -322,22 +322,15 @@ ieee80211_input(struct ieee80211vap * va
- 			}
- 			/* Do not try to find a node reference if the packet really did come from the BSS */
- 			if (type == IEEE80211_FC0_TYPE_DATA && ni == vap->iv_bss &&
--					!IEEE80211_ADDR_EQ(vap->iv_bss->ni_macaddr, wh->i_addr2) &&
- 					IEEE80211_ADDR_EQ(vap->iv_bssid, wh->i_addr3)) {
- 				/* Try to find sender in local node table. */
--				ni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
-+				if (!ni_or_null) {
-+					ieee80211_unref_node(&ni);
-+					ni = ieee80211_find_txnode(vap, wh->i_addr2);
-+				}
- 				if (ni == NULL) {
--					/*
--					 * Fake up a node for this newly discovered
--					 * member of the IBSS.  This should probably
--					 * done after an ACL check.
--					 */
--					ni = ieee80211_fakeup_adhoc_node(vap,
--							wh->i_addr2);
--					if (ni == NULL) {
--						/* NB: stat kept for alloc failure */
--						goto err;
--					}
-+					/* NB: stat kept for alloc failure */
-+					goto discard;
- 				}
- 			}
- 			iwspy_event(vap, ni, rssi);
-@@ -3553,8 +3546,8 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 				(((vap->iv_opmode == IEEE80211_M_HOSTAP) ||
- 				 (vap->iv_opmode == IEEE80211_M_WDS)) &&
- 				(scan.capinfo & IEEE80211_CAPINFO_ESS))) {
-+			struct ieee80211_node *tni = NULL;
- 			struct ieee80211vap *avp = NULL;
--			int do_unref = 0;
- 			int found = 0;
- 
- 			IEEE80211_LOCK_IRQ(vap->iv_ic);
-@@ -3570,14 +3563,12 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 					}
- 				}
- 				if (found)
--					ni = ni_or_null = avp->iv_wdsnode;
-+					tni = ieee80211_ref_node(avp->iv_wdsnode);
- 			} else if ((vap->iv_opmode == IEEE80211_M_WDS) && vap->iv_wdsnode) {
- 				found = 1;
--				ni = ni_or_null = vap->iv_wdsnode;
--			} else if (vap->iv_opmode == IEEE80211_M_IBSS) {
--				ni_or_null = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
--				if (ni_or_null)
--					ni = ni_or_null;
-+				tni = ieee80211_ref_node(vap->iv_wdsnode);
-+			} else if ((vap->iv_opmode == IEEE80211_M_IBSS) && (vap->iv_state == IEEE80211_S_RUN)) {
-+				tni = ieee80211_find_node(&ic->ic_sta, wh->i_addr2);
- 				found = 1;
- 			}
- 			IEEE80211_UNLOCK_IRQ(vap->iv_ic);
-@@ -3585,20 +3576,21 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 			if (!found)
- 				break;
- 
--			if (ni_or_null == NULL) {
-+			memcpy(&SKB_CB(skb)->beacon_tsf, scan.tstamp, sizeof(u_int64_t));
-+
-+			if (tni == NULL) {
- 				if (avp) {
- 					IEEE80211_LOCK_IRQ(ic);
--					ni = ieee80211_add_neighbor(avp, wh, &scan);
-+					tni = ieee80211_add_neighbor(avp, wh, &scan);
- 					/* force assoc */
--					ni->ni_associd |= 0xc000;
--					avp->iv_wdsnode = ieee80211_ref_node(ni);
-+					tni->ni_associd |= 0xc000;
-+					avp->iv_wdsnode = ieee80211_ref_node(tni);
- 					IEEE80211_UNLOCK_IRQ(ic);
- 				} else if ((vap->iv_opmode == IEEE80211_M_IBSS) &&
- 				           IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid)) {
- 					/* Create a new entry in the neighbor table. */
--					ni = ieee80211_add_neighbor(vap, wh, &scan);
-+					tni = ieee80211_add_neighbor(vap, wh, &scan);
- 				}
--				do_unref = 1;
- 			} else {
- 				/*
- 				 * Copy data from beacon to neighbor table.
-@@ -3606,39 +3598,38 @@ ieee80211_recv_mgmt(struct ieee80211vap
- 				 * ieee80211_add_neighbor(), so we just copy
- 				 * everything over to be safe.
- 				 */
--				ni->ni_esslen = scan.ssid[1];
--				memcpy(ni->ni_essid, scan.ssid + 2, scan.ssid[1]);
--				IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
--				memcpy(ni->ni_tstamp.data, scan.tstamp,
--					sizeof(ni->ni_tstamp));
--				ni->ni_inact = ni->ni_inact_reload;
--				ni->ni_intval = 
-+				tni->ni_esslen = scan.ssid[1];
-+				memcpy(tni->ni_essid, scan.ssid + 2, scan.ssid[1]);
-+				IEEE80211_ADDR_COPY(tni->ni_bssid, wh->i_addr3);
-+				memcpy(tni->ni_tstamp.data, scan.tstamp,
-+					sizeof(tni->ni_tstamp));
-+				tni->ni_inact = tni->ni_inact_reload;
-+				tni->ni_intval =
- 					IEEE80211_BINTVAL_SANITISE(scan.bintval);
--				ni->ni_capinfo = scan.capinfo;
--				ni->ni_chan = ic->ic_curchan;
--				ni->ni_fhdwell = scan.fhdwell;
--				ni->ni_fhindex = scan.fhindex;
--				ni->ni_erp = scan.erp;
--				ni->ni_timoff = scan.timoff;
-+				tni->ni_capinfo = scan.capinfo;
-+				tni->ni_chan = ic->ic_curchan;
-+				tni->ni_fhdwell = scan.fhdwell;
-+				tni->ni_fhindex = scan.fhindex;
-+				tni->ni_erp = scan.erp;
-+				tni->ni_timoff = scan.timoff;
- 				if (scan.wme != NULL)
--					ieee80211_saveie(&ni->ni_wme_ie, scan.wme);
-+					ieee80211_saveie(&tni->ni_wme_ie, scan.wme);
- 				if (scan.wpa != NULL)
--					ieee80211_saveie(&ni->ni_wpa_ie, scan.wpa);
-+					ieee80211_saveie(&tni->ni_wpa_ie, scan.wpa);
- 				if (scan.rsn != NULL)
--					ieee80211_saveie(&ni->ni_rsn_ie, scan.rsn);
-+					ieee80211_saveie(&tni->ni_rsn_ie, scan.rsn);
- 				if (scan.ath != NULL)
--					ieee80211_saveath(ni, scan.ath);
-+					ieee80211_saveath(tni, scan.ath);
- 
- 				/* NB: must be after ni_chan is setup */
--				ieee80211_setup_rates(ni, scan.rates,
-+				ieee80211_setup_rates(tni, scan.rates,
- 					scan.xrates, IEEE80211_F_DOSORT);
- 			}
--			if (ni != NULL) {
--				ni->ni_rssi = rssi;
--				ni->ni_rtsf = rtsf;
--				ni->ni_last_rx = jiffies;
--				if (do_unref)
--					ieee80211_unref_node(&ni);
-+			if (tni != NULL) {
-+				tni->ni_rssi = rssi;
-+				tni->ni_rtsf = rtsf;
-+				tni->ni_last_rx = jiffies;
-+				ieee80211_unref_node(&tni);
- 			}
- 		}
- 		break;
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -53,6 +53,7 @@
- 
- #include <net80211/ieee80211_var.h>
- #include <net80211/if_athproto.h>
-+#include <net80211/ieee80211_node.h>
- 
- /*
-  * Association IDs are managed with a bit vector.
-@@ -317,16 +318,11 @@ ieee80211_create_ibss(struct ieee80211va
- 	/* Check to see if we already have a node for this mac
- 	 * NB: we gain a node reference here
- 	 */
--	ni = ieee80211_find_txnode(vap, vap->iv_myaddr);
-+	ieee80211_node_table_reset(&ic->ic_sta, vap);
-+	ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr);
- 	if (ni == NULL) {
--		ni = ieee80211_alloc_node_table(vap, vap->iv_myaddr);
--		IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
--				  "%s: ni:%p allocated for " MAC_FMT "\n",
--				  __func__, ni, MAC_ADDR(vap->iv_myaddr));
--		if (ni == NULL) {
--			/* XXX recovery? */
--			return;
--		}
-+		/* XXX recovery? */
-+		return;
- 	}
- 
- 	IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_myaddr);
-@@ -647,7 +643,7 @@ ieee80211_sta_join1(struct ieee80211_nod
- 		(vap->iv_state == IEEE80211_S_RUN) && bssid_equal(obss, selbs)); */
- 	vap->iv_bss = selbs;
- 	IEEE80211_ADDR_COPY(vap->iv_bssid, selbs->ni_bssid);
--	if (obss != NULL) {
-+	if ((obss != NULL) && (obss != selbs)) {
- 		if (obss->ni_table)
- 			ieee80211_node_leave(obss);
- 		ieee80211_unref_node(&obss);
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -6625,14 +6625,6 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 
- 	sc->sc_recv_mgmt(vap, ni_or_null, skb, subtype, rssi, rtsf);
- 
--	/* Lookup the new node if any (this grabs a reference to it) */
--	ni = ieee80211_find_rxnode(vap->iv_ic, vap,
--	         (const struct ieee80211_frame_min *)skb->data);
--	if (ni == NULL) {
--		DPRINTF(sc, ATH_DEBUG_BEACON, "Dropping; node unknown.\n");
--		return;
--	}
--
- 	switch (subtype) {
- 	case IEEE80211_FC0_SUBTYPE_BEACON:
- 		/* update RSSI statistics for use by the HAL */
-@@ -6654,11 +6646,9 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 			 * we do the IBSS merging in software. Also do not merge
- 			 * if the difference it too small. Otherwise we are playing
- 			 * tsf-pingpong with other vendors drivers */
--			beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf);
--			if (beacon_tsf > rtsf + 0xffff) {
-+			beacon_tsf = le64_to_cpu(SKB_CB(skb)->beacon_tsf);
-+			if (beacon_tsf > rtsf + 0xffff)
- 				ath_hal_settsf64(sc->sc_ah, beacon_tsf - rtsf);
--				ieee80211_ibss_merge(ni);
--			}
- 			break;
- 		}
- 		/* NB: Fall Through */
-@@ -6680,13 +6670,21 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 			hw_tsf = ath_hal_gettsf64(sc->sc_ah);
- 			hw_tu  = hw_tsf >> 10;
- 
--			beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf);
-+			beacon_tsf = le64_to_cpu(SKB_CB(skb)->beacon_tsf);
- 			beacon_tu  = beacon_tsf >> 10;
- 
-+			if (!beacon_tsf)
-+				break;
-+
-+			if (IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid))
-+				break;
-+
- 			DPRINTF(sc, ATH_DEBUG_BEACON,
--					"Beacon transmitted at %10llx, "
-+					"Beacon transmitted from "MAC_FMT" ("MAC_FMT") at %10llx, "
- 					"received at %10llx(%lld), hw TSF "
- 					"%10llx(%lld)\n",
-+					MAC_ADDR(wh->i_addr3),
-+					MAC_ADDR(vap->iv_bssid),
- 					beacon_tsf,
- 					rtsf, rtsf - beacon_tsf,
- 					hw_tsf, hw_tsf - beacon_tsf);
-@@ -6699,39 +6697,13 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 				do_merge = 1;
- 			}
- 
--			/* Check sc_nexttbtt */
--			if (sc->sc_nexttbtt < hw_tu) {
--				DPRINTF(sc, ATH_DEBUG_BEACON,
--					"sc_nexttbtt (%8x TU) is in the past "
--					"(tsf %8x TU), updating timers\n",
--					sc->sc_nexttbtt, hw_tu);
--				do_merge = 1;
--			}
--
--			intval = ni->ni_intval & HAL_BEACON_PERIOD;
--#if 0
--			/* This code is disabled since it would produce
--			 * unwanted merge. For instance, in a two nodes network
--			 * A & B, A can merge to B and at the same time, B will
--			 * merge to A, still having a split */
--			if (intval != 0) {
--				if ((sc->sc_nexttbtt % intval) !=
--						(beacon_tu % intval)) {
--					DPRINTF(sc, ATH_DEBUG_BEACON,
--							"ibss merge: "
--							"sc_nexttbtt %10x TU "
--							"(%3d) beacon %10x TU "
--							"(%3d)\n",
--							sc->sc_nexttbtt,
--							sc->sc_nexttbtt % intval,
--							beacon_tu,
--							beacon_tu % intval);
--					do_merge = 1;
--				}
--			}
--#endif
--			if (do_merge)
-+			if (do_merge) {
-+				/* Lookup the new node if any (this grabs a reference to it) */
-+				ni = ieee80211_find_txnode(vap, wh->i_addr2);
-+				memcpy(ni->ni_bssid, wh->i_addr3, IEEE80211_ADDR_LEN);
- 				ieee80211_ibss_merge(ni);
-+				ieee80211_unref_node(&ni);
-+			}
- 
- 			if ((sc->sc_opmode == HAL_M_IBSS) &&
- 					ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval))
-@@ -6739,8 +6711,6 @@ ath_recv_mgmt(struct ieee80211vap * vap,
- 		}
- 		break;
- 	}
--
--	ieee80211_unref_node(&ni);
- }
- 
- static void
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -411,7 +411,7 @@ typedef spinlock_t acl_lock_t;
-  *     8 bytes so we reserve/avoid it.
-  */
- 	struct ieee80211_cb {
--	u_int8_t vlan[8];			/* reserve for vlan tag info */
-+	u_int64_t beacon_tsf;
- 	struct ieee80211_node *ni;
- 	u_int32_t flags;
- #define	M_LINK0		0x01			/* frame needs WEP encryption */
---- a/net80211/ieee80211_scan_sta.c
-+++ b/net80211/ieee80211_scan_sta.c
-@@ -1125,11 +1125,8 @@ adhoc_default_action(struct ieee80211vap
- 	u_int8_t zeroMacAddr[IEEE80211_ADDR_LEN];
- 
- 	memset(&zeroMacAddr, 0, IEEE80211_ADDR_LEN);
--	if (IEEE80211_ADDR_EQ(se->se_bssid, &zeroMacAddr[0])) {
--		ieee80211_create_ibss(vap, se->se_chan);
--		return 1;
--	} else
--		return ieee80211_sta_join(vap, se);
-+	ieee80211_create_ibss(vap, se->se_chan);
-+	return 1;
- }
- 
- static const struct ieee80211_scanner adhoc_default = {
diff --git a/package/madwifi/patches/452-minstrel_no_timer.patch b/package/madwifi/patches/452-minstrel_no_timer.patch
deleted file mode 100644
index f0f5c26f93..0000000000
--- a/package/madwifi/patches/452-minstrel_no_timer.patch
+++ /dev/null
@@ -1,134 +0,0 @@
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -119,6 +119,7 @@
- #include "minstrel.h"
- 
- #define ONE_SECOND (1000 * 1000)  /* 1 second, or 1000 milliseconds; eternity, in other words */
-+#define TIMER_INTERVAL 100 /* msecs */
- 
- #include "release.h"
- 
-@@ -128,9 +129,6 @@ static char *dev_info = "ath_rate_minstr
- #define STALE_FAILURE_TIMEOUT_MS 10000
- #define ENABLE_MRR 1
- 
--static int ath_timer_interval = (1000 / 10); /* every 1/10 second, timer runs */
--static void ath_timer_function(unsigned long data);
--
- /* 10% of the time, send a packet at something other than the optimal rate, which fills
-  * the statistics tables nicely. This percentage is applied to the first packet of the
-  * multi rate retry chain. */
-@@ -142,7 +140,7 @@ static void ath_rate_ctl_reset(struct at
- /* Calculate the throughput and probability of success for each node
-  * we are talking on, based on the statistics collected during the
-  * last timer period. */
--static void ath_rate_statistics(void *arg, struct ieee80211_node *ni);
-+static void ath_rate_statistics(struct ieee80211_node *ni);
- 
- 
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
-@@ -204,6 +202,11 @@ ath_rate_findrate(struct ath_softc *sc,
- 		unsigned int ndx, offset;
- 		int mrr;
- 
-+
-+		if (abs(jiffies - sn->last_update) > msecs_to_jiffies(TIMER_INTERVAL)) {
-+			ath_rate_statistics(&an->an_node);
-+			sn->last_update = jiffies;
-+		}
- 		if (sn->num_rates <= 0) {
- 			    printk(KERN_WARNING "%s: no rates for " MAC_FMT "?\n",
- 			           dev_info,
-@@ -640,54 +643,11 @@ ath_rate_newstate(struct ieee80211vap *v
- 		}
- }
- 
--static void
--ath_timer_function(unsigned long data)
--{
--		struct minstrel_softc *ssc = (struct minstrel_softc *) data;
--		struct ath_softc *sc = ssc->sc;
--		struct ieee80211com *ic;
--		struct net_device *dev = ssc->sc_dev;
--		struct timer_list *timer;
--		unsigned int interval = ath_timer_interval;
--
--		if (dev == NULL)
--			DPRINTF(sc, ATH_DEBUG_RATE, "%s: 'dev' is null in this timer \n", __func__);
--
--		if (sc == NULL)
--			DPRINTF(sc, ATH_DEBUG_RATE, "%s: 'sc' is null in this timer\n", __func__);
--
--		ic = &sc->sc_ic;
--
--		if (ssc->close_timer_now)
--			return;
--
--		if (dev->flags & IFF_RUNNING) {
--			sc->sc_stats.ast_rate_calls++;
--
--			if (ic->ic_opmode == IEEE80211_M_STA) {
--				struct ieee80211vap *tmpvap;
--				TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
--					ath_rate_statistics(sc, tmpvap->iv_bss);/* NB: no reference */
--				}
--			} else
--			            ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_statistics, sc);
--		}
--
--		if (ic->ic_opmode == IEEE80211_M_STA)
--			interval = ath_timer_interval >> 1;
--
--		timer  = &(ssc->timer);
--		if (timer == NULL)
--			DPRINTF(sc, ATH_DEBUG_RATE, "%s: timer is null - leave it\n", __func__);
--
--		timer->expires = jiffies + ((HZ * interval) / 1000);
--		add_timer(timer);
--}
- 
- static void
--ath_rate_statistics(void *arg, struct ieee80211_node *ni)
-+ath_rate_statistics(struct ieee80211_node *ni)
- {
--		struct ath_node *an = (struct ath_node *) ni;
-+		struct ath_node *an = ATH_NODE(ni);
- 		struct ieee80211_rateset *rs = &ni->ni_rates;
- 		struct minstrel_node *rn = ATH_NODE_MINSTREL(an);
- 		unsigned int i;
-@@ -786,15 +746,8 @@ ath_rate_attach(struct ath_softc *sc)
- 		osc->arc.arc_space = sizeof(struct minstrel_node);
- 		osc->arc.arc_vap_space = 0;
- 
--		osc->close_timer_now = 0;
--		init_timer(&osc->timer);
-  	osc->sc          = sc;
- 		osc->sc_dev      = sc->sc_dev;
--		osc->timer.function = ath_timer_function;
--		osc->timer.data = (unsigned long)osc;
--
--		osc->timer.expires = jiffies + HZ;
--		add_timer(&osc->timer);
- 
- 		return &osc->arc;
- }
-@@ -803,8 +756,6 @@ static void
- ath_rate_detach(struct ath_ratectrl *arc)
- {
-  	struct minstrel_softc *osc = (struct minstrel_softc *) arc;
--		osc->close_timer_now = 1;
--		del_timer(&osc->timer);
- 		kfree(osc);
- 		_MOD_DEC_USE(THIS_MODULE);
- }
---- a/ath_rate/minstrel/minstrel.h
-+++ b/ath_rate/minstrel/minstrel.h
-@@ -167,6 +167,8 @@ struct minstrel_node {
- 	       packet, or a packet at an optimal rate.*/
- 	int random_n;
- 	int a, b;          /**Coefficients of the random thing */
-+
-+	unsigned long last_update;
- };
- 
- 
diff --git a/package/madwifi/patches/453-procps.patch b/package/madwifi/patches/453-procps.patch
deleted file mode 100644
index 5a5633b1ca..0000000000
--- a/package/madwifi/patches/453-procps.patch
+++ /dev/null
@@ -1,55 +0,0 @@
---- a/net80211/ieee80211_linux.h
-+++ b/net80211/ieee80211_linux.h
-@@ -640,12 +640,24 @@ static __inline unsigned long msecs_to_j
- 	  void __user *buffer, size_t *lenp)
- #define	IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
- 	proc_dointvec(ctl, write, filp, buffer, lenp)
--#else
-+#define IEEE80211_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
-+        proc_dostring(ctl, write, filp, buffer, lenp)
-+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
- #define	IEEE80211_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
- 	f(ctl_table *ctl, int write, struct file *filp, \
- 	  void __user *buffer, size_t *lenp, loff_t *ppos)
- #define	IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
- 	proc_dointvec(ctl, write, filp, buffer, lenp, ppos)
-+#define IEEE80211_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
-+        proc_dostring(ctl, write, filp, buffer, lenp, ppos)
-+#else /* Linux 2.6.32+ */
-+#define	IEEE80211_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
-+	f(ctl_table *ctl, int write, \
-+	  void __user *buffer, size_t *lenp, loff_t *ppos)
-+#define	IEEE80211_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
-+	proc_dointvec(ctl, write, buffer, lenp, ppos)
-+#define IEEE80211_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
-+        proc_dostring(ctl, write, buffer, lenp, ppos)
- #endif
- 
- void ieee80211_virtfs_latevattach(struct ieee80211vap *);
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -173,14 +173,22 @@ static inline struct net_device *_alloc_
- 	proc_dointvec(ctl, write, filp, buffer, lenp)
- #define	ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
- 	proc_dostring(ctl, write, filp, buffer, lenp)
--#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) */
-+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
- #define	ATH_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
- 	f(ctl_table *ctl, int write, struct file *filp, \
- 	  void __user *buffer, size_t *lenp, loff_t *ppos)
- #define	ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
- 	proc_dointvec(ctl, write, filp, buffer, lenp, ppos)
-+#define ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
-+        proc_dostring(ctl, write, filp, buffer, lenp, ppos)
-+#else /* Linux 2.6.32+ */
-+#define	ATH_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
-+	f(ctl_table *ctl, int write, \
-+	  void __user *buffer, size_t *lenp, loff_t *ppos)
-+#define	ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
-+	proc_dointvec(ctl, write, buffer, lenp, ppos)
- #define	ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
--	proc_dostring(ctl, write, filp, buffer, lenp, ppos)
-+	proc_dostring(ctl, write, buffer, lenp, ppos)
- #endif
- 
- #define	ATH_TIMEOUT	1000
diff --git a/package/madwifi/patches/454-cca.patch b/package/madwifi/patches/454-cca.patch
deleted file mode 100644
index 53792cc8fa..0000000000
--- a/package/madwifi/patches/454-cca.patch
+++ /dev/null
@@ -1,186 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -383,6 +383,8 @@ static void ath_poll_disable(struct net_
- static void ath_poll_enable(struct net_device *dev);
- static void ath_fetch_idle_time(struct ath_softc *sc);
- static void ath_set_timing(struct ath_softc *sc);
-+static void ath_update_cca_thresh(struct ath_softc *sc);
-+static int ath_hw_read_nf(struct ath_softc *sc);
- 
- /* calibrate every 30 secs in steady state but check every second at first. */
- static int ath_calinterval = ATH_SHORT_CALINTERVAL;
-@@ -2623,6 +2625,10 @@ ath_init(struct net_device *dev)
- 		goto done;
- 	}
- 
-+	ath_hal_process_noisefloor(ah);
-+	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
-+	ath_update_cca_thresh(sc);
-+
- 	if (sc->sc_softled)
- 		ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
- 
-@@ -3024,6 +3030,10 @@ ath_reset(struct net_device *dev)
- 		EPRINTF(sc, "Unable to reset hardware: '%s' (HAL status %u)\n",
- 			ath_get_hal_status_desc(status), status);
- 
-+	ath_hal_process_noisefloor(ah);
-+	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
-+	ath_update_cca_thresh(sc);
-+
- 	ath_setintmit(sc);
- 	ath_update_txpow(sc);		/* update tx power state */
- 	ath_radar_update(sc);
-@@ -9374,9 +9384,11 @@ ath_calibrate(unsigned long arg)
- 			sc->sc_curchan.channel);
- 		sc->sc_stats.ast_per_calfail++;
- 	}
--	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
- 
- 	ath_hal_process_noisefloor(ah);
-+	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
-+	ath_update_cca_thresh(sc);
-+
- 	if (isIQdone == AH_TRUE) {
- 		/* Unless user has overridden calibration interval,
- 		 * upgrade to less frequent calibration */
-@@ -9711,8 +9723,6 @@ ath_newstate(struct ieee80211vap *vap, e
- 			break;
- 		}
- 
--		ath_hal_process_noisefloor(ah);
--		ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
- 		/*
- 		 * Reset rssi stats; maybe not the best place...
- 		 */
-@@ -10968,6 +10978,7 @@ enum {
- 	ATH_INTMIT,
- 	ATH_NOISE_IMMUNITY,
- 	ATH_OFDM_WEAK_DET,
-+	ATH_CCA_THRESH,
- 	ATH_CHANBW,
- 	ATH_OUTDOOR,
- 	ATH_DISTANCE,
-@@ -11110,6 +11121,66 @@ ath_sysctl_get_intmit(struct ath_softc *
- 	return 0;
- }
- 
-+#define AR_PHY_CCA              0x9864
-+#define AR_PHY_MINCCA_PWR       0x0FF80000
-+#define AR_PHY_MINCCA_PWR_S     19
-+#define AR_PHY_CCA_THRESH62     0x0007F000
-+#define AR_PHY_CCA_THRESH62_S   12
-+
-+static int
-+ath_nf_from_cca(u32 phy_cca)
-+{
-+	int nf = (phy_cca >> 19) & 0x1ff;
-+	nf = -((nf ^ 0x1ff) + 1);
-+	return nf;
-+}
-+
-+static int
-+ath_hw_read_nf(struct ath_softc *sc)
-+{
-+	return ath_nf_from_cca(OS_REG_READ(sc->sc_ah, AR_PHY_CCA));
-+}
-+
-+static void
-+ath_update_cca_thresh(struct ath_softc *sc)
-+{
-+	struct ath_hal *ah = sc->sc_ah;
-+	int newthr = 0;
-+	u32 phy_cca;
-+	int nf;
-+
-+	phy_cca = OS_REG_READ(ah, AR_PHY_CCA);
-+	if (sc->sc_cca_thresh < 0) {
-+		newthr = sc->sc_cca_thresh - ath_nf_from_cca(phy_cca);
-+
-+		/* 0xf is a typical eeprom value for thresh62,
-+		 * use it as minimum for signal based thresholds
-+		 * to prevent complete connection drops */
-+		if (newthr < 0xf)
-+			newthr = 0xf;
-+	} else {
-+		newthr = sc->sc_cca_thresh;
-+	}
-+
-+	if ((newthr < 4) || (newthr >= 127))
-+		return;
-+
-+	phy_cca &= ~AR_PHY_CCA_THRESH62;
-+	phy_cca |= newthr << AR_PHY_CCA_THRESH62_S;
-+	OS_REG_WRITE(ah, AR_PHY_CCA, phy_cca);
-+}
-+
-+static int
-+ath_get_cca_thresh(struct ath_softc *sc)
-+{
-+	struct ath_hal *ah = sc->sc_ah;
-+	u32 phy_cca;
-+
-+	phy_cca = OS_REG_READ(ah, AR_PHY_CCA);
-+	return ath_nf_from_cca(phy_cca) +
-+		((phy_cca & AR_PHY_CCA_THRESH62) >> AR_PHY_CCA_THRESH62_S);
-+}
-+
- static int
- ATH_SYSCTL_DECL(ath_sysctl_hwinfo, ctl, write, filp, buffer, lenp, ppos)
- {
-@@ -11356,6 +11427,10 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 			case ATH_OFDM_WEAK_DET:
- 				ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val);
- 				break;
-+			case ATH_CCA_THRESH:
-+				sc->sc_cca_thresh = val;
-+				ath_update_cca_thresh(sc);
-+				break;
- 			default:
- 				ret = -EINVAL;
- 				break;
-@@ -11436,6 +11511,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 		case ATH_OFDM_WEAK_DET:
- 			ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val);
- 			break;
-+		case ATH_CCA_THRESH:
-+			val = ath_get_cca_thresh(sc);
-+			break;
- 		default:
- 			ret = -EINVAL;
- 			break;
-@@ -11667,6 +11745,12 @@ static const ctl_table ath_sysctl_templa
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_OFDM_WEAK_DET,
- 	},
-+	{ .ctl_name	= CTL_AUTO,
-+	  .procname     = "cca_thresh",
-+	  .mode         = 0644,
-+	  .proc_handler = ath_sysctl_halparam,
-+	  .extra2	= (void *)ATH_CCA_THRESH,
-+	},
- 	{ 0 }
- };
- 
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -844,6 +844,7 @@ struct ath_softc {
- 	int sc_cal_interval;			/* current calibration interval */
- 	struct timer_list sc_cal_ch;		/* calibration timer */
- 	HAL_NODE_STATS sc_halstats;		/* station-mode rssi stats */
-+	int sc_cca_thresh;				/* configured CCA threshold */
- 
- 	struct ctl_table_header *sc_sysctl_header;
- 	struct ctl_table *sc_sysctls;
---- a/ath/ath_wprobe.c
-+++ b/ath/ath_wprobe.c
-@@ -133,8 +133,7 @@ ath_wprobe_sync(struct wprobe_iface *dev
- 	rx = READ_CLR(ah, AR5K_RXFC);
- 	tx = READ_CLR(ah, AR5K_TXFC);
- 	OS_REG_WRITE(ah, AR5K_MIBC, 0);
--	noise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan));
--	ic->ic_channoise = noise;
-+	noise = ath_hw_read_nf(sc);
- 
- 	WPROBE_FILL_BEGIN(val, ath_wprobe_globals);
- 	if (cc & 0xf0000000) {
diff --git a/package/madwifi/patches/455-beacon_watchdog.patch b/package/madwifi/patches/455-beacon_watchdog.patch
deleted file mode 100644
index d0b4fa63e1..0000000000
--- a/package/madwifi/patches/455-beacon_watchdog.patch
+++ /dev/null
@@ -1,95 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -379,6 +379,7 @@ static u_int32_t ath_get_clamped_maxtxpo
- static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc, 
- 		u_int32_t new_clamped_maxtxpower);
- 
-+static void ath_bcn_timer(unsigned long arg);
- static void ath_poll_disable(struct net_device *dev);
- static void ath_poll_enable(struct net_device *dev);
- static void ath_fetch_idle_time(struct ath_softc *sc);
-@@ -829,6 +830,10 @@ ath_attach(u_int16_t devid, struct net_d
- 	sc->sc_cal_ch.function = ath_calibrate;
- 	sc->sc_cal_ch.data = (unsigned long) dev;
- 
-+	init_timer(&sc->sc_bcntimer);
-+	sc->sc_bcntimer.function = ath_bcn_timer;
-+	sc->sc_bcntimer.data = (unsigned long) dev;
-+
- 	/* initialize DFS related variables */
- 	sc->sc_dfswait = 0;
- 	sc->sc_dfs_cac = 0;
-@@ -2704,6 +2709,7 @@ ath_stop_locked(struct net_device *dev)
- 	DPRINTF(sc, ATH_DEBUG_RESET, "invalid=%u flags=0x%x\n",
- 		sc->sc_invalid, dev->flags);
- 
-+	del_timer_sync(&sc->sc_bcntimer);
- 	if (dev->flags & IFF_RUNNING) {
- 		/*
- 		 * Shutdown the hardware and driver:
-@@ -3006,6 +3012,7 @@ ath_reset(struct net_device *dev)
- 	struct ieee80211_channel *c;
- 	HAL_STATUS status;
- 
-+	del_timer_sync(&sc->sc_bcntimer);
- 	/*
- 	 * XXX: starting the calibration too early seems to lead to
- 	 * problems with the beacons.
-@@ -5305,6 +5312,7 @@ ath_beacon_send(struct ath_softc *sc, in
- 	if (ath_chan_unavail_dbgmsg(sc))
- 		return;
- 
-+	mod_timer(&sc->sc_bcntimer, jiffies + sc->sc_bcntimer_reload);
- 	/*
- 	 * Check if the previous beacon has gone out.  If
- 	 * not don't try to post another, skip this period
-@@ -5487,6 +5495,18 @@ ath_beacon_free(struct ath_softc *sc)
- 		cleanup_ath_buf(sc, bf, BUS_DMA_TODEVICE);
- }
- 
-+static void ath_bcn_timer(unsigned long arg)
-+{
-+	struct net_device *dev = (struct net_device *)arg;
-+	struct ath_softc *sc = netdev_priv(dev);
-+	struct ath_hal *ah = sc->sc_ah;
-+
-+	if (!sc->sc_beacons)
-+		return;
-+
-+	ath_reset(dev);
-+}
-+
- /*
-  * Configure the beacon and sleep timers.
-  *
-@@ -5523,6 +5543,7 @@ ath_beacon_config(struct ath_softc *sc,
- 	if (vap == NULL)
- 		vap = TAILQ_FIRST(&ic->ic_vaps);   /* XXX */
- 
-+	del_timer_sync(&sc->sc_bcntimer);
- 	ni = vap->iv_bss;
- 
- 	/* TSF calculation is timing critical - we don't want to be interrupted here */
-@@ -5699,6 +5720,9 @@ ath_beacon_config(struct ath_softc *sc,
- 			sc->sc_imask |= HAL_INT_SWBA;
- 			ath_set_beacon_cal(sc, 1);
- 			ath_beaconq_config(sc);
-+
-+			sc->sc_bcntimer_reload = msecs_to_jiffies(10 * (intval & HAL_BEACON_PERIOD));
-+			mod_timer(&sc->sc_bcntimer, jiffies + sc->sc_bcntimer_reload);
- 		} else
- 			ath_set_beacon_cal(sc, 0);
- 
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -789,6 +789,10 @@ struct ath_softc {
- 	u_int16_t sc_ledoff;			/* off time for current blink */
- 	struct timer_list sc_ledtimer;		/* led off timer */
- 
-+	/* beacon watchdog timer */
-+	u_int32_t sc_bcntimer_reload;
-+	struct timer_list sc_bcntimer;
-+
- 	struct ATH_TQ_STRUCT sc_fataltq;	/* fatal error intr tasklet */
- 
- 	int sc_rxbufsize;			/* rx size based on mtu */
diff --git a/package/madwifi/patches/456-rfsilent.patch b/package/madwifi/patches/456-rfsilent.patch
deleted file mode 100644
index 21031e7ca2..0000000000
--- a/package/madwifi/patches/456-rfsilent.patch
+++ /dev/null
@@ -1,85 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -2996,6 +2996,19 @@ ath_fetch_idle_time(struct ath_softc *sc
- #undef AR5K_RXCLEAR
- #undef AR5K_CYCLES
- 
-+static void
-+ath_set_silent(struct ath_softc *sc)
-+{
-+	struct ath_hal *ah = sc->sc_ah;
-+
-+	if (!sc->sc_silent)
-+		return;
-+
-+	del_timer_sync(&sc->sc_bcntimer);
-+	ath_hal_intrset(ah, 0);
-+	OS_REG_WRITE(ah, 0x8048, 0x60); /* set tx loopback and rx disable */
-+}
-+
- /*
-  * Reset the hardware w/o losing operational state.  This is
-  * basically a more efficient way of doing ath_stop, ath_init,
-@@ -3073,6 +3086,7 @@ ath_reset(struct net_device *dev)
- 		ath_grppoll_start(vap, sc->sc_xrpollcount);
- 	}
- #endif
-+	ath_set_silent(sc);
- 	return 0;
- }
- 
-@@ -10972,6 +10986,7 @@ enum {
-  * mirrored in /proc/sys.
-  */
- enum {
-+	ATH_SILENT,
- 	ATH_SLOTTIME,
- 	ATH_ACKTIMEOUT,
- 	ATH_CTSTIMEOUT,
-@@ -11294,6 +11309,13 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 					sc->sc_ctstimeconf = 0;
- 				ath_set_timing(sc);
- 				break;
-+			case ATH_SILENT:
-+				sc->sc_silent = !!val;
-+				if (val)
-+					ath_set_silent(sc);
-+				else
-+					ath_reset(sc->sc_dev);
-+				break;
- 			case ATH_DISTANCE:
- 				if (val > 0) {
- 					sc->sc_coverage = ((val - 1) / 300) + 1;
-@@ -11477,6 +11499,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
- 		case ATH_CTSTIMEOUT:
- 			val = ath_hal_getctstimeout(ah);
- 			break;
-+		case ATH_SILENT:
-+			val = sc->sc_silent;
-+			break;
- 		case ATH_SOFTLED:
- 			val = sc->sc_softled;
- 			break;
-@@ -11598,6 +11623,12 @@ static const ctl_table ath_sysctl_templa
- 	  .extra2	= (void *)ATH_DISTANCE,
- 	},
- 	{ .ctl_name	= CTL_AUTO,
-+	  .procname	= "silent",
-+	  .mode		= 0644,
-+	  .proc_handler	= ath_sysctl_halparam,
-+	  .extra2	= (void *)ATH_SILENT,
-+	},
-+	{ .ctl_name	= CTL_AUTO,
- 	  .procname	= "softled",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -737,6 +737,7 @@ struct ath_softc {
- 						 * 'channel availability check' indefinately,
- 						 * reporting radar and interference detections.
- 						 */
-+	unsigned int	sc_silent:1;	/* Turn RF silent */
- 	unsigned int sc_txcont_power; /* Continuous transmit power in 0.5dBm units */
- 	unsigned int sc_txcont_rate;  /* Continuous transmit rate in Mbps */
- 
diff --git a/package/madwifi/patches/457-idletime.patch b/package/madwifi/patches/457-idletime.patch
deleted file mode 100644
index 429da85225..0000000000
--- a/package/madwifi/patches/457-idletime.patch
+++ /dev/null
@@ -1,151 +0,0 @@
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -355,6 +355,8 @@ ieee80211_ifattach(struct ieee80211com *
- 	/* Arbitrarily pick the first channel */
- 	ic->ic_curchan = &ic->ic_channels[0];
- 
-+	ic->ic_inact_tick = IEEE80211_INACT_WAIT;
-+
- 	/* Enable marking of dfs by default */
- 	ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS;
- 
---- a/net80211/ieee80211_var.h
-+++ b/net80211/ieee80211_var.h
-@@ -350,6 +350,7 @@ struct ieee80211com {
- 	u_int8_t ic_protmode_rssi;			/* rssi threshold for protection mode */
- 	u_int64_t ic_protmode_lasttrig;		/* last trigger for protection mode */
- 	u_int16_t ic_protmode_timeout;		/* protection mode timeout */
-+	u_int16_t ic_inact_tick;			/* inact timer tick interval (seconds) */
- 
- 	/* Channel state:
- 	 *
---- a/net80211/ieee80211_ioctl.h
-+++ b/net80211/ieee80211_ioctl.h
-@@ -591,6 +591,7 @@ enum {
- 	IEEE80211_PARAM_INACT_AUTH		= 24,	/* station auth inact timeout */
- 	IEEE80211_PARAM_INACT_INIT		= 25,	/* station init inact timeout */
- 	IEEE80211_PARAM_ABOLT			= 26,	/* Atheros Adv. Capabilities */
-+	IEEE80211_PARAM_INACT_TICK		= 27,	/* station inactivity timer tick (seconds) */
- 	IEEE80211_PARAM_DTIM_PERIOD		= 28,	/* DTIM period (beacons) */
- 	IEEE80211_PARAM_BEACON_INTERVAL		= 29,	/* beacon interval (ms) */
- 	IEEE80211_PARAM_DOTH			= 30,	/* 11.h is on/off */
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -2504,13 +2504,18 @@ ieee80211_ioctl_setparam(struct net_devi
- 			vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
- 		break;
- 	case IEEE80211_PARAM_INACT:
--		vap->iv_inact_run = value / IEEE80211_INACT_WAIT;
-+		vap->iv_inact_run = value / ic->ic_inact_tick;
-+		break;
-+	case IEEE80211_PARAM_INACT_TICK:
-+		if (value <= 0)
-+			return -EINVAL;
-+		ic->ic_inact_tick = value;
- 		break;
- 	case IEEE80211_PARAM_INACT_AUTH:
--		vap->iv_inact_auth = value / IEEE80211_INACT_WAIT;
-+		vap->iv_inact_auth = value / ic->ic_inact_tick;
- 		break;
- 	case IEEE80211_PARAM_INACT_INIT:
--		vap->iv_inact_init = value / IEEE80211_INACT_WAIT;
-+		vap->iv_inact_init = value / ic->ic_inact_tick;
- 		break;
- 	case IEEE80211_PARAM_ABOLT:
- 		caps = 0;
-@@ -3050,13 +3055,16 @@ ieee80211_ioctl_getparam(struct net_devi
- 		param[0] = (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0;
- 		break;
- 	case IEEE80211_PARAM_INACT:
--		param[0] = vap->iv_inact_run * IEEE80211_INACT_WAIT;
-+		param[0] = vap->iv_inact_run * ic->ic_inact_tick;
- 		break;
- 	case IEEE80211_PARAM_INACT_AUTH:
--		param[0] = vap->iv_inact_auth * IEEE80211_INACT_WAIT;
-+		param[0] = vap->iv_inact_auth * ic->ic_inact_tick;
- 		break;
- 	case IEEE80211_PARAM_INACT_INIT:
--		param[0] = vap->iv_inact_init * IEEE80211_INACT_WAIT;
-+		param[0] = vap->iv_inact_init * ic->ic_inact_tick;
-+		break;
-+	case IEEE80211_PARAM_INACT_TICK:
-+		param[0] = ic->ic_inact_tick;
- 		break;
- 	case IEEE80211_PARAM_ABOLT:
- 		/*
-@@ -4557,14 +4565,7 @@ get_sta_info(void *arg, struct ieee80211
- 		si->isi_opmode = IEEE80211_STA_OPMODE_XR;
- 	else
- 		si->isi_opmode = IEEE80211_STA_OPMODE_NORMAL;
--	/* NB: leave all cases in case we relax ni_associd == 0 check */
--	if (ieee80211_node_is_authorized(ni))
--		si->isi_inact = vap->iv_inact_run;
--	else if (ni->ni_associd != 0)
--		si->isi_inact = vap->iv_inact_auth;
--	else
--		si->isi_inact = vap->iv_inact_init;
--	si->isi_inact = (si->isi_inact - ni->ni_inact) * IEEE80211_INACT_WAIT;
-+	si->isi_inact = (ni->ni_inact_reload - ni->ni_inact) * ic->ic_inact_tick;
- 
- 	cp = (u_int8_t *)(si+1);
- 	if (ni->ni_rsn_ie != NULL) {
-@@ -5597,6 +5598,10 @@ static const struct iw_priv_args ieee802
- 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "inact_init" },
- 	{ IEEE80211_PARAM_INACT_INIT,
- 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_inact_init" },
-+	{ IEEE80211_PARAM_INACT_TICK,
-+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "inact_tick" },
-+	{ IEEE80211_PARAM_INACT_TICK,
-+	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_inact_tick" },
- 	{ IEEE80211_PARAM_ABOLT,
- 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "abolt" },
- 	{ IEEE80211_PARAM_ABOLT,
---- a/net80211/ieee80211_node.c
-+++ b/net80211/ieee80211_node.c
-@@ -137,7 +137,7 @@ ieee80211_node_attach(struct ieee80211co
- 	init_timer(&ic->ic_inact);
- 	ic->ic_inact.function = ieee80211_node_timeout;
- 	ic->ic_inact.data = (unsigned long) ic;
--	ic->ic_inact.expires = jiffies + IEEE80211_INACT_WAIT * HZ;
-+	ic->ic_inact.expires = jiffies + ic->ic_inact_tick * HZ;
- 	add_timer(&ic->ic_inact);
- 
- #ifdef IEEE80211_DEBUG_REFCNT
-@@ -261,7 +261,7 @@ void
- ieee80211_node_authorize(struct ieee80211_node *ni)
- {
- 	ni->ni_flags |= IEEE80211_NODE_AUTH;
--	ni->ni_inact_reload = ni->ni_vap->iv_inact_run;
-+	ni->ni_inact = ni->ni_inact_reload = ni->ni_vap->iv_inact_run;
- }
- EXPORT_SYMBOL(ieee80211_node_authorize);
- 
-@@ -1819,7 +1819,7 @@ ieee80211_node_timeout(unsigned long arg
- 		}
- 	}
- 
--	ic->ic_inact.expires = jiffies + IEEE80211_INACT_WAIT * HZ;
-+	ic->ic_inact.expires = jiffies + ic->ic_inact_tick * HZ;
- 	add_timer(&ic->ic_inact);
- }
- 
---- a/net80211/ieee80211_power.c
-+++ b/net80211/ieee80211_power.c
-@@ -148,7 +148,7 @@ ieee80211_node_saveq_age(struct ieee8021
- 
- 		IEEE80211_NODE_SAVEQ_LOCK_IRQ(ni);
- 		while ((skb = skb_peek(&ni->ni_savedq)) != NULL &&
--		     M_AGE_GET(skb) < IEEE80211_INACT_WAIT) {
-+		     M_AGE_GET(skb) <  ni->ni_vap->iv_ic->ic_inact_tick) {
- 			IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
- 				"discard frame, age %u", M_AGE_GET(skb));
- 
-@@ -159,7 +159,7 @@ ieee80211_node_saveq_age(struct ieee8021
- 			discard++;
- 		}
- 		if (skb != NULL)
--			M_AGE_SUB(skb, IEEE80211_INACT_WAIT);
-+			M_AGE_SUB(skb, ni->ni_vap->iv_ic->ic_inact_tick);
- 		IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni);
- 
- 		IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
diff --git a/package/madwifi/patches/458-ibss_wpa_none.patch b/package/madwifi/patches/458-ibss_wpa_none.patch
deleted file mode 100644
index df77510b2a..0000000000
--- a/package/madwifi/patches/458-ibss_wpa_none.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/net80211/ieee80211_crypto_ccmp.c
-+++ b/net80211/ieee80211_crypto_ccmp.c
-@@ -273,7 +273,9 @@ ccmp_decap(struct ieee80211_key *k, stru
- 		tid = ((struct ieee80211_qosframe *)wh)->i_qos[0] & IEEE80211_QOS_TID;
- 	/* NB: assume IEEE80211_WEP_MINLEN covers the extended IV */
- 	pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);
--	if (pn && pn <= k->wk_keyrsc[tid]) {
-+	if ((vap->iv_opmode != IEEE80211_M_IBSS) &&
-+	    (vap->iv_opmode != IEEE80211_M_AHDEMO) &&
-+	    (pn && pn <= k->wk_keyrsc[tid])) {
- 		/*
- 		 * Replay violation.
- 		 */
diff --git a/package/madwifi/patches/459-2.6.33_compile.patch b/package/madwifi/patches/459-2.6.33_compile.patch
deleted file mode 100644
index 4e08a011a4..0000000000
--- a/package/madwifi/patches/459-2.6.33_compile.patch
+++ /dev/null
@@ -1,524 +0,0 @@
---- a/kernelversion.c
-+++ b/kernelversion.c
-@@ -10,7 +10,11 @@
- 
- /* Linux 2.6.18+ uses <linux/utsrelease.h> */
- #ifndef UTS_RELEASE
--#include <linux/utsrelease.h>
-+  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)
-+    #include <generated/utsrelease.h>
-+  #else
-+    #include <linux/utsrelease.h>
-+  #endif
- #endif
- 
- char *uts_release = UTS_RELEASE;
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -11580,227 +11580,231 @@ static int mincalibrate = 1;		/* once a
- static int maxint = 0x7fffffff;		/* 32-bit big */
- 
- static const ctl_table ath_sysctl_template[] = {
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "dev_vendor",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_hwinfo,
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- 	  .strategy   = &sysctl_string,
-+#endif
- 	  .data		= "N/A",
- 	  .maxlen   = 1,
- 	  .extra2	= (void *)ATH_CARD_VENDOR,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "dev_name",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_hwinfo,
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- 	  .strategy   = &sysctl_string,
-+#endif
- 	  .data		= "N/A",
- 	  .maxlen   = 1,
- 	  .extra2	= (void *)ATH_CARD_NAME,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "slottime",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_SLOTTIME,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "acktimeout",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_ACKTIMEOUT,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "ctstimeout",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_CTSTIMEOUT,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "distance",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_DISTANCE,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "silent",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_SILENT,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "softled",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_SOFTLED,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "ledpin",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_LEDPIN,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "countrycode",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_COUNTRYCODE,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "outdoor",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_OUTDOOR,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "regdomain",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_REGDOMAIN,
- 	},
- #ifdef AR_DEBUG
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "debug",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_DEBUG,
- 	},
- #endif
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "poweroffset",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_POWEROFFSET,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "txantenna",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_TXANTENNA,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "rxantenna",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RXANTENNA,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "diversity",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_DIVERSITY,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "txintrperiod",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_TXINTRPERIOD,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "fftxqmin",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_FFTXQMIN,
- 	},
- #ifdef ATH_SUPERG_XR
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "xrpollperiod",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_XR_POLL_PERIOD,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "xrpollcount",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_XR_POLL_COUNT,
- 	},
- #endif
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "ackrate",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_ACKRATE,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "channelbw",
- 	  .mode		= 0644,
- 	  .proc_handler	= ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_CHANBW,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "rp",
- 	  .mode         = 0200,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RP,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "radar_print",
- 	  .mode         = 0200,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RP_PRINT,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "radar_print_all",
- 	  .mode         = 0200,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RP_PRINT_ALL,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "radar_dump",
- 	  .mode         = 0200,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RP_PRINT_MEM,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "radar_dump_all",
- 	  .mode         = 0200,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RP_PRINT_MEM_ALL,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "rp_flush",
- 	  .mode         = 0200,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RP_FLUSH,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "panic",
- 	  .mode         = 0200,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_PANIC,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "rp_ignored",
- 	  .mode         = 0644,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RP_IGNORED,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "radar_ignored",
- 	  .mode         = 0644,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_RADAR_IGNORED,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "intmit",
- 	  .mode         = 0644,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_INTMIT,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "noise_immunity",
- 	  .mode         = 0644,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_NOISE_IMMUNITY,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "ofdm_weak_det",
- 	  .mode         = 0644,
- 	  .proc_handler = ath_sysctl_halparam,
- 	  .extra2	= (void *)ATH_OFDM_WEAK_DET,
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname     = "cca_thresh",
- 	  .mode         = 0644,
- 	  .proc_handler = ath_sysctl_halparam,
-@@ -11838,12 +11842,16 @@ ath_dynamic_sysctl_register(struct ath_s
- 
- 	/* setup the table */
- 	memset(sc->sc_sysctls, 0, space);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- 	sc->sc_sysctls[0].ctl_name = CTL_DEV;
-+#endif
- 	sc->sc_sysctls[0].procname = "dev";
- 	sc->sc_sysctls[0].mode = 0555;
- 	sc->sc_sysctls[0].child = &sc->sc_sysctls[2];
- 	/* [1] is NULL terminator */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- 	sc->sc_sysctls[2].ctl_name = CTL_AUTO;
-+#endif
- 	sc->sc_sysctls[2].procname = dev_name;
- 	sc->sc_sysctls[2].mode = 0555;
- 	sc->sc_sysctls[2].child = &sc->sc_sysctls[4];
-@@ -11966,7 +11974,7 @@ ath_announce(struct net_device *dev)
-  */
- static ctl_table ath_static_sysctls[] = {
- #ifdef AR_DEBUG
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "debug",
- 	  .mode		= 0644,
- 	  .data		= &ath_debug,
-@@ -11974,14 +11982,14 @@ static ctl_table ath_static_sysctls[] =
- 	  .proc_handler	= proc_dointvec
- 	},
- #endif
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "xchanmode",
- 	  .mode		= 0444,
- 	  .data		= &ath_xchanmode,
- 	  .maxlen	= sizeof(ath_xchanmode),
- 	  .proc_handler	= proc_dointvec
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "calibrate",
- 	  .mode		= 0644,
- 	  .data		= &ath_calinterval,
-@@ -11993,14 +12001,14 @@ static ctl_table ath_static_sysctls[] =
- 	{ 0 }
- };
- static ctl_table ath_ath_table[] = {
--	{ .ctl_name	= DEV_ATH,
-+	{ CTLNAME(DEV_ATH)
- 	  .procname	= "ath",
- 	  .mode		= 0555,
- 	  .child	= ath_static_sysctls
- 	}, { 0 }
- };
- static ctl_table ath_root_table[] = {
--	{ .ctl_name	= CTL_DEV,
-+	{ CTLNAME(CTL_DEV)
- 	  .procname	= "dev",
- 	  .mode		= 0555,
- 	  .child	= ath_ath_table
---- a/ath/if_ath_ahb.h
-+++ b/ath/if_ath_ahb.h
-@@ -112,7 +112,11 @@
- 	do { (void) (start); (void) (size); } while (0)
- #endif
- 
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
-+#define bus_dma_sync_single	dma_sync_single_for_cpu
-+#else
- #define bus_dma_sync_single	dma_sync_single
-+#endif
- #define bus_map_single		dma_map_single
- #define bus_unmap_single	dma_unmap_single
- #define bus_alloc_consistent(_hwdev, _sz, _hdma)		\
---- a/ath_hal/ah_os.c
-+++ b/ath_hal/ah_os.c
-@@ -518,7 +518,7 @@ EXPORT_SYMBOL(ath_hal_memcmp);
- 
- static ctl_table ath_hal_sysctls[] = {
- #ifdef AH_DEBUG
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "debug",
- 	  .mode		= 0644,
- 	  .data		= &ath_hal_debug,
-@@ -526,21 +526,21 @@ static ctl_table ath_hal_sysctls[] = {
- 	  .proc_handler	= proc_dointvec
- 	},
- #endif
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "dma_beacon_response_time",
- 	  .data		= &ath_hal_dma_beacon_response_time,
- 	  .maxlen	= sizeof(ath_hal_dma_beacon_response_time),
- 	  .mode		= 0644,
- 	  .proc_handler	= proc_dointvec
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "sw_beacon_response_time",
- 	  .mode		= 0644,
- 	  .data		= &ath_hal_sw_beacon_response_time,
- 	  .maxlen	= sizeof(ath_hal_sw_beacon_response_time),
- 	  .proc_handler	= proc_dointvec
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "swba_backoff",
- 	  .mode		= 0644,
- 	  .data		= &ath_hal_additional_swba_backoff,
-@@ -548,19 +548,19 @@ static ctl_table ath_hal_sysctls[] = {
- 	  .proc_handler	= proc_dointvec
- 	},
- #ifdef AH_DEBUG_ALQ
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "alq",
- 	  .mode		= 0644,
- 	  .proc_handler	= sysctl_hw_ath_hal_log
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "alq_size",
- 	  .mode		= 0644,
- 	  .data		= &ath_hal_alq_qsize,
- 	  .maxlen	= sizeof(ath_hal_alq_qsize),
- 	  .proc_handler	= proc_dointvec
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "alq_lost",
- 	  .mode		= 0644,
- 	  .data		= &ath_hal_alq_lost,
-@@ -571,21 +571,21 @@ static ctl_table ath_hal_sysctls[] = {
- 	{ 0 }
- };
- static ctl_table ath_hal_table[] = {
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "hal",
- 	  .mode		= 0555,
- 	  .child	= ath_hal_sysctls
- 	}, { 0 }
- };
- static ctl_table ath_ath_table[] = {
--	{ .ctl_name	= DEV_ATH,
-+	{ CTLNAME(DEV_ATH)
- 	  .procname	= "ath",
- 	  .mode		= 0555,
- 	  .child	= ath_hal_table
- 	}, { 0 }
- };
- static ctl_table ath_root_table[] = {
--	{ .ctl_name	= CTL_DEV,
-+	{ CTLNAME(CTL_DEV)
- 	  .procname	= "dev",
- 	  .mode		= 0555,
- 	  .child	= ath_ath_table
---- a/include/compat.h
-+++ b/include/compat.h
-@@ -193,6 +193,12 @@ static inline int timeval_compare(struct
- #define __skb_queue_after(_list, _old, _new)	__skb_append(_old, _new, _list)
- #endif
- 
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
-+#define CTLNAME(x)	.ctl_name	= x,
-+#else
-+#define CTLNAME(x)
-+#endif
-+
- #endif /* __KERNEL__ */
- 
- #endif /* _ATH_COMPAT_H_ */
---- a/net80211/ieee80211_linux.c
-+++ b/net80211/ieee80211_linux.c
-@@ -699,39 +699,39 @@ IEEE80211_SYSCTL_DECL(ieee80211_sysctl_m
- 
- static const ctl_table ieee80211_sysctl_template[] = {
- #ifdef IEEE80211_DEBUG
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "debug",
- 	  .mode		= 0644,
- 	  .proc_handler	= ieee80211_sysctl_debug
- 	},
- #endif
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "dev_type",
- 	  .mode		= 0644,
- 	  .proc_handler	= ieee80211_sysctl_dev_type
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "monitor_nods_only",
- 	  .mode		= 0644,
- 	  .proc_handler	= ieee80211_sysctl_monitor_nods_only
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "monitor_txf_len",
- 	  .mode		= 0644,
- 	  .proc_handler	= ieee80211_sysctl_monitor_txf_len
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "monitor_phy_errors",
- 	  .mode		= 0644,
- 	  .proc_handler = ieee80211_sysctl_monitor_phy_errors
- 	},
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "monitor_crc_errors",
- 	  .mode		= 0644,
- 	  .proc_handler = ieee80211_sysctl_monitor_crc_errors
- 	},
- 	/* NB: must be last entry before NULL */
--	{ .ctl_name	= CTL_AUTO,
-+	{ CTLNAME(CTL_AUTO)
- 	  .procname	= "%parent",
- 	  .maxlen	= IFNAMSIZ,
- 	  .mode		= 0444,
-@@ -786,12 +786,16 @@ ieee80211_virtfs_latevattach(struct ieee
- 
- 	/* setup the table */
- 	memset(vap->iv_sysctls, 0, space);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- 	vap->iv_sysctls[0].ctl_name = CTL_NET;
-+#endif
- 	vap->iv_sysctls[0].procname = "net";
- 	vap->iv_sysctls[0].mode = 0555;
- 	vap->iv_sysctls[0].child = &vap->iv_sysctls[2];
- 	/* [1] is NULL terminator */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- 	vap->iv_sysctls[2].ctl_name = CTL_AUTO;
-+#endif
- 	vap->iv_sysctls[2].procname = devname; /* XXX bad idea? */
- 	vap->iv_sysctls[2].mode = 0555;
- 	vap->iv_sysctls[2].child = &vap->iv_sysctls[4];
diff --git a/package/madwifi/patches/460-pci_softled_disable.patch b/package/madwifi/patches/460-pci_softled_disable.patch
deleted file mode 100644
index 328e8c3505..0000000000
--- a/package/madwifi/patches/460-pci_softled_disable.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/ath/if_ath_pci.c
-+++ b/ath/if_ath_pci.c
-@@ -264,6 +264,7 @@ ath_pci_probe(struct pci_dev *pdev, cons
- 		}
- 	}
- 
-+#if 0
- 	/*
- 	 * Auto-enable soft led processing for IBM cards and for
- 	 * 5211 minipci cards.  Users can also manually enable/disable
-@@ -279,6 +280,7 @@ ath_pci_probe(struct pci_dev *pdev, cons
- 		sc->aps_sc.sc_softled = 1;
- 		sc->aps_sc.sc_ledpin = 1;
- 	}
-+#endif
- 
- 	if ((i = ath_attach(vdevice, dev, NULL)) != 0) {
- 		printk(KERN_ERR "%s: ath_attach failed: %d\n", dev_info, i);
diff --git a/package/madwifi/patches/461-rx_stats_count_fix.patch b/package/madwifi/patches/461-rx_stats_count_fix.patch
deleted file mode 100644
index 4b5ce28cc0..0000000000
--- a/package/madwifi/patches/461-rx_stats_count_fix.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -202,7 +202,6 @@ ieee80211_input(struct ieee80211vap * va
- 	struct ieee80211com *ic;
- 	struct net_device *dev;
- 	struct ieee80211_node *ni_wds = NULL;
--	struct net_device_stats *stats;
- 	struct ieee80211_frame *wh;
- 	struct ieee80211_key *key;
- 	struct ether_header *eh;
-@@ -685,12 +684,6 @@ ieee80211_input(struct ieee80211vap * va
- 		if (! accept_data_frame(vap, ni, key, skb, eh))
- 			goto out;
- 
--		if (ni->ni_subif && ((eh)->ether_type != __constant_htons(ETHERTYPE_PAE)))
--			stats = &ni->ni_subif->iv_devstats;
--		else
--			stats = &vap->iv_devstats;
--		stats->rx_packets++;
--		stats->rx_bytes += skb->len;
- 		IEEE80211_NODE_STAT(ni, rx_data);
- 		IEEE80211_NODE_STAT_ADD(ni, rx_bytes, skb->len);
- 		ic->ic_lastdata = jiffies;
diff --git a/package/madwifi/patches/462-fix_ap_scan.patch b/package/madwifi/patches/462-fix_ap_scan.patch
deleted file mode 100644
index 8798f534ec..0000000000
--- a/package/madwifi/patches/462-fix_ap_scan.patch
+++ /dev/null
@@ -1,26 +0,0 @@
---- a/net80211/ieee80211_scan_ap.c
-+++ b/net80211/ieee80211_scan_ap.c
-@@ -595,6 +595,14 @@ ap_end(struct ieee80211_scan_state *ss,
- 
- 	ic = vap->iv_ic;
- 
-+	/* if we're already running, switch back to the home channel */
-+	if ((vap->iv_state == IEEE80211_S_RUN) &&
-+	    (ic->ic_bsschan != IEEE80211_CHAN_ANYC)) {
-+		ic->ic_curchan = ic->ic_bsschan;
-+		ic->ic_set_channel(ic);
-+		goto out;
-+	}
-+
- 	/* record stats for the channel that was scanned last */
- 	ic->ic_set_channel(ic);
- 	spin_lock_irqsave(&channel_lock, sflags);
-@@ -648,6 +656,8 @@ ap_end(struct ieee80211_scan_state *ss,
- 		IEEE80211_SCHEDULE_TQUEUE(&as->as_actiontq);
- 		res = 1;
- 	}
-+
-+out:
- 	SCAN_AP_UNLOCK_IRQ(as);
- 	return res;
- }
diff --git a/package/madwifi/patches/463-fix_txrate_display.patch b/package/madwifi/patches/463-fix_txrate_display.patch
deleted file mode 100644
index 0889f78fec..0000000000
--- a/package/madwifi/patches/463-fix_txrate_display.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/ath_rate/minstrel/minstrel.c
-+++ b/ath_rate/minstrel/minstrel.c
-@@ -728,6 +728,7 @@ ath_rate_statistics(struct ieee80211_nod
- 		rn->max_tp_rate2  = index_max_tp2;
- 		rn->max_prob_rate = index_max_prob;
- 		rn->current_rate  = index_max_tp;
-+		ni->ni_txrate = index_max_tp;
- }
- 
- static struct ath_ratectrl *
diff --git a/package/madwifi/patches/464-0dbm_txpower_fix.patch b/package/madwifi/patches/464-0dbm_txpower_fix.patch
deleted file mode 100644
index fbd1d7673c..0000000000
--- a/package/madwifi/patches/464-0dbm_txpower_fix.patch
+++ /dev/null
@@ -1,30 +0,0 @@
---- a/net80211/ieee80211_wireless.c
-+++ b/net80211/ieee80211_wireless.c
-@@ -1370,15 +1370,9 @@ ieee80211_ioctl_siwtxpow(struct net_devi
- 	int fixed, disabled;
- 
- 	fixed = (ic->ic_flags & IEEE80211_F_TXPOW_FIXED);
--	disabled = (fixed && ic->ic_txpowlimit == 0);
--	if (rrq->disabled) {
--		if (!disabled) {
--			ic->ic_flags |= IEEE80211_F_TXPOW_FIXED;
--			ic->ic_txpowlimit = 0;
--			goto done;
--		}
--		return 0;
--	}
-+
-+	if (rrq->disabled)
-+		return -EINVAL;
- 
- 	if (rrq->fixed) {
- 		if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0)
-@@ -1571,7 +1565,7 @@ ieee80211_ioctl_giwtxpow(struct net_devi
- 		rrq->fixed = 0;
- 	}
- 	rrq->value = txp / 2;
--	rrq->disabled = (rrq->fixed && rrq->value == 0);
-+	rrq->disabled = 0;
- 	rrq->flags = IW_TXPOW_DBM;
- 	return 0;
- }
diff --git a/package/madwifi/patches/465-mc_list-2.6.35.patch b/package/madwifi/patches/465-mc_list-2.6.35.patch
deleted file mode 100644
index 4931cfb282..0000000000
--- a/package/madwifi/patches/465-mc_list-2.6.35.patch
+++ /dev/null
@@ -1,40 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -4466,7 +4466,11 @@ ath_merge_mcast(struct ath_softc *sc, u_
- {
- 	struct ieee80211com *ic = &sc->sc_ic;
- 	struct ieee80211vap *vap;
-+	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) 
-+	struct netdev_hw_addr *ha; 
-+	#else
- 	struct dev_mc_list *mc;
-+	#endif
- 	u_int32_t val;
- 	u_int8_t pos;
- 
-@@ -4474,6 +4478,17 @@ ath_merge_mcast(struct ath_softc *sc, u_
- 	/* XXX locking */
- 	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- 		struct net_device *dev = vap->iv_dev;
-+		#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
-+		netdev_for_each_mc_addr(ha, dev) { 
-+			/* calculate XOR of eight 6-bit values */
-+			val = LE_READ_4(ha->addr + 0);
-+			pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
-+			val = LE_READ_4(ha->addr + 3);
-+			pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
-+			pos &= 0x3f;
-+			mfilt[pos / 32] |= (1 << (pos % 32));
-+		}
-+		#else
- 		for (mc = dev->mc_list; mc; mc = mc->next) {
- 			/* calculate XOR of eight 6-bit values */
- 			val = LE_READ_4(mc->dmi_addr + 0);
-@@ -4483,6 +4498,7 @@ ath_merge_mcast(struct ath_softc *sc, u_
- 			pos &= 0x3f;
- 			mfilt[pos / 32] |= (1 << (pos % 32));
- 		}
-+		#endif 
- 	}
- }
- 
diff --git a/package/madwifi/patches/466-2.6.38_compile.patch b/package/madwifi/patches/466-2.6.38_compile.patch
deleted file mode 100644
index 10a6f0debb..0000000000
--- a/package/madwifi/patches/466-2.6.38_compile.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- a/include/compat.h
-+++ b/include/compat.h
-@@ -131,6 +131,11 @@
- #ifdef __KERNEL__
- 
- #include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
-+#define AUTOCONF_INCLUDED 1
-+#endif
-+
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
- #define ATH_REGISTER_SYSCTL_TABLE(t) register_sysctl_table(t, 1)
- #else
diff --git a/package/madwifi/patches/470-mac_addresss_from_ath5k_platform_data.patch b/package/madwifi/patches/470-mac_addresss_from_ath5k_platform_data.patch
deleted file mode 100644
index 0c35050c51..0000000000
--- a/package/madwifi/patches/470-mac_addresss_from_ath5k_platform_data.patch
+++ /dev/null
@@ -1,36 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -63,6 +63,8 @@
- #include <linux/rtnetlink.h>
- #include <linux/time.h>
- #include <linux/pci.h>
-+#include <linux/device.h>
-+#include <linux/ath5k_platform.h>
- #include <asm/uaccess.h>
- 
- #include "if_ethersubr.h"		/* for ETHER_IS_MULTICAST */
-@@ -587,6 +589,10 @@ ath_attach(u_int16_t devid, struct net_d
- 	unsigned int i;
- 	int autocreatemode = -1;
- 	u_int8_t csz;
-+#ifdef ATH_PCI
-+	struct ath5k_platform_data *pdata;
-+	struct pci_dev *pdev;
-+#endif
- 
- 	sc->devid = devid;
- #ifdef AR_DEBUG
-@@ -648,6 +654,13 @@ ath_attach(u_int16_t devid, struct net_d
- 	}
- 	sc->sc_ah = ah;
- 
-+#ifdef ATH_PCI
-+	/* set MAC from ath_platform_data */
-+	pdev = (struct pci_dev *)sc->sc_bdev;
-+	pdata = pdev->dev.platform_data;
-+	if (pdata && pdata->macaddr)
-+		ath_hal_setmac(ah, pdata->macaddr);
-+#endif
- 	/* WAR for AR7100 PCI bug */
- #if defined(CONFIG_ATHEROS_AR71XX) || defined(CONFIG_ATH79)
- 	if ((ar_device(sc->devid) >= 5210) && (ar_device(sc->devid) < 5416)) {
diff --git a/package/madwifi/patches/471-netdev_ops_mac_mtu.patch b/package/madwifi/patches/471-netdev_ops_mac_mtu.patch
deleted file mode 100644
index c7e1f404af..0000000000
--- a/package/madwifi/patches/471-netdev_ops_mac_mtu.patch
+++ /dev/null
@@ -1,30 +0,0 @@
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -47,6 +47,7 @@
- #include <linux/skbuff.h>
- #include <linux/netdevice.h>
- #include <linux/rtnetlink.h>		/* XXX for rtnl_lock */
-+#include <linux/etherdevice.h>
- 
- #include "if_media.h"
- 
-@@ -463,6 +464,8 @@ static const struct net_device_ops ieee8
- 	.ndo_set_multicast_list = ieee80211_set_multicast_list,
- 	.ndo_change_mtu 	= ieee80211_change_mtu,
- 	.ndo_do_ioctl		= ieee80211_ioctl,
-+	.ndo_validate_addr	= eth_validate_addr,
-+	.ndo_set_mac_address	= eth_mac_addr,
- };
- #endif
- 
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -574,6 +574,8 @@ static const struct net_device_ops ath_n
- 	.ndo_get_stats		= ath_getstats,
- 	.ndo_set_mac_address	= ath_set_mac_address,
- 	.ndo_change_mtu 	= ath_change_mtu,
-+	.ndo_validate_addr	= eth_validate_addr,
-+	.ndo_set_mac_address	= eth_mac_addr,
- };
- #endif
- 
diff --git a/package/madwifi/patches/472-remove_11n_devids.patch b/package/madwifi/patches/472-remove_11n_devids.patch
deleted file mode 100644
index cf80f06bf6..0000000000
--- a/package/madwifi/patches/472-remove_11n_devids.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/ath/if_ath_pci.c
-+++ b/ath/if_ath_pci.c
-@@ -111,8 +111,6 @@ static struct pci_device_id ath_pci_id_t
- 	{ 0x168c, 0x001b, PCI_ANY_ID, PCI_ANY_ID },
- 	{ 0x168c, 0x001c, PCI_ANY_ID, PCI_ANY_ID }, /* PCI Express 5424 */
- 	{ 0x168c, 0x001d, PCI_ANY_ID, PCI_ANY_ID }, /* PCI Express ???  */
--	{ 0x168c, 0x0023, PCI_ANY_ID, PCI_ANY_ID },
--	{ 0x168c, 0x0024, PCI_ANY_ID, PCI_ANY_ID },
- 	{ 0x168c, 0x9013, PCI_ANY_ID, PCI_ANY_ID }, /* sonicwall */
- 	{ 0x168c, 0xff1a, PCI_ANY_ID, PCI_ANY_ID },
- 	{ 0 }
-@@ -146,8 +144,6 @@ static const struct ath_hw_detect cards[
- 	{ ubnt, "SR4C",    0x168c, 0x0013, 0x7777, 0x1004, 6 },
- 	{ ubnt, "SR5",     0x168c, 0x0013, 0x168c, 0x2042, 7 },
- 	{ ubnt, "SR9",     0x168c, 0x0013, 0x7777, 0x2009, 12 },
--	{ ubnt, "SR71A",   0x168c, 0x0027, 0x168c, 0x2082, 10 },
--	{ ubnt, "SR71",    0x168c, 0x0027, 0x0777, 0x4082, 10 },
- };
- 
- static int
diff --git a/package/madwifi/patches/473-mutex_fix.patch b/package/madwifi/patches/473-mutex_fix.patch
deleted file mode 100644
index 22cea46a26..0000000000
--- a/package/madwifi/patches/473-mutex_fix.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ath/if_athvar.h
-+++ b/ath/if_athvar.h
-@@ -974,7 +974,7 @@ typedef void (*ath_callback) (struct ath
- #endif
- 
- /* Protects the device from concurrent accesses */
--#define	ATH_LOCK_INIT(_sc)		init_MUTEX(&(_sc)->sc_lock)
-+#define	ATH_LOCK_INIT(_sc)		sema_init(&(_sc)->sc_lock, 1)
- #define	ATH_LOCK_DESTROY(_sc)
- #define	ATH_LOCK(_sc)			down(&(_sc)->sc_lock)
- #define	ATH_UNLOCK(_sc)			up(&(_sc)->sc_lock)
diff --git a/package/madwifi/patches/474_fix_ssid_scan_length.patch b/package/madwifi/patches/474_fix_ssid_scan_length.patch
deleted file mode 100644
index 2e85e18c64..0000000000
--- a/package/madwifi/patches/474_fix_ssid_scan_length.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/tools/wlanconfig.c
-+++ b/tools/wlanconfig.c
-@@ -654,7 +654,7 @@ static void
- list_scan(const char *ifname)
- {
- 	static uint8_t buf[24 * 1024];
--	char ssid[14];
-+	char ssid[30];
- 	uint8_t *cp;
- 	int len;
- 
-@@ -665,7 +665,7 @@ list_scan(const char *ifname)
- 	if (len < sizeof(struct ieee80211req_scan_result))
- 		return;
- 
--	printf("%-14.14s  %-17.17s  %4s %4s  %-5s %3s %4s\n",
-+	printf("%-30.30s  %-17.17s  %4s %4s  %-5s %3s %4s\n",
- 		"SSID",
- 		"BSSID",
- 		"CHAN",
-@@ -680,7 +680,7 @@ list_scan(const char *ifname)
- 
- 		sr = (struct ieee80211req_scan_result *) cp;
- 		vp = (u_int8_t *)(sr+1);
--		printf("%-14.*s  %s  %3d  %3dM %2d:%-2d  %3d %-4.4s",
-+		printf("%-30.*s  %s  %3d  %3dM %2d:%-2d  %3d %-4.4s",
- 			copy_essid(ssid, sizeof(ssid), vp, sr->isr_ssid_len),
- 			ssid,
- 			ieee80211_ntoa(sr->isr_bssid),
diff --git a/package/madwifi/patches/475-2.6.39-compile.patch b/package/madwifi/patches/475-2.6.39-compile.patch
deleted file mode 100644
index 5b8a777187..0000000000
--- a/package/madwifi/patches/475-2.6.39-compile.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/net80211/ieee80211_scan.c
-+++ b/net80211/ieee80211_scan.c
-@@ -97,7 +97,7 @@ struct scan_state {
- static void scan_restart_pwrsav(unsigned long);
- static void scan_next(unsigned long);
- 
--spinlock_t channel_lock = SPIN_LOCK_UNLOCKED;
-+DEFINE_SPINLOCK(channel_lock);
- static LIST_HEAD(channels_inuse);
- 
- struct channel_inuse {
diff --git a/package/madwifi/patches/476-3.0_detection_fix.patch b/package/madwifi/patches/476-3.0_detection_fix.patch
deleted file mode 100644
index 2f8bfb4a55..0000000000
--- a/package/madwifi/patches/476-3.0_detection_fix.patch
+++ /dev/null
@@ -1,25 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -155,13 +155,15 @@ unload:
- configcheck:
- 	@echo -n "Checking kernel configuration... "
- 	
--	@# check version of kernel
--	@echo $(KERNELRELEASE) | grep -q -i '^[2-9]\.[4-9]\.' || { \
--	    echo "FAILED"; \
--	    echo "Only kernel versions 2.4.x and above are supported."; \
--	    echo "You have $(KERNELRELEASE)."; \
--	    exit 1; \
--	}
-+	@# check kernel version
-+	@case $(KERNELRELEASE) in \
-+	    2.[456].*) ;; \
-+	    [3-9].*) ;; \
-+	    *) echo "FAILED"; \
-+	       echo "Only kernel versions 2.4.x and above are supported."; \
-+	       echo "You have $(KERNELRELEASE)."; \
-+	       exit 1 ;; \
-+	esac
- 	
- 	@# check kernel configuration
- 	@if [ -z "$(CONFIG_SYSCTL)" ]; then \
diff --git a/package/madwifi/patches/477-3.2_fixes.patch b/package/madwifi/patches/477-3.2_fixes.patch
deleted file mode 100644
index 89cdfc6494..0000000000
--- a/package/madwifi/patches/477-3.2_fixes.patch
+++ /dev/null
@@ -1,45 +0,0 @@
---- a/ath/if_ath.c
-+++ b/ath/if_ath.c
-@@ -569,7 +569,11 @@ static const struct net_device_ops ath_n
- 	.ndo_stop		= ath_stop,
- 	.ndo_start_xmit		= ath_hardstart,
- 	.ndo_tx_timeout 	= ath_tx_timeout,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
-+	.ndo_set_rx_mode	= ath_mode_init,
-+#else
- 	.ndo_set_multicast_list = ath_mode_init,
-+#endif
- 	.ndo_do_ioctl		= ath_ioctl,
- 	.ndo_get_stats		= ath_getstats,
- 	.ndo_set_mac_address	= ath_set_mac_address,
---- a/net80211/ieee80211.c
-+++ b/net80211/ieee80211.c
-@@ -461,7 +461,11 @@ static const struct net_device_ops ieee8
- 	.ndo_open		= ieee80211_open,
- 	.ndo_stop		= ieee80211_stop,
- 	.ndo_start_xmit		= ieee80211_hardstart,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
-+	.ndo_set_rx_mode	= ieee80211_set_multicast_list,
-+#else
- 	.ndo_set_multicast_list = ieee80211_set_multicast_list,
-+#endif
- 	.ndo_change_mtu 	= ieee80211_change_mtu,
- 	.ndo_do_ioctl		= ieee80211_ioctl,
- 	.ndo_validate_addr	= eth_validate_addr,
-@@ -1847,10 +1851,14 @@ ieee80211_set_multicast_list(struct net_
- 	IEEE80211_UNLOCK_IRQ(ic);
- 
- 	/* XXX: Merge multicast list into parent device */
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
--	parent->set_multicast_list(ic->ic_dev);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
-+	parent->netdev_ops->ndo_set_rx_mode(ic->ic_dev);
- #else
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
- 	parent->netdev_ops->ndo_set_multicast_list(ic->ic_dev);
-+#else
-+	parent->set_multicast_list(ic->ic_dev);
-+#endif
- #endif
- }
- 
diff --git a/package/madwifi/patches/478-remove_vlan_code.patch b/package/madwifi/patches/478-remove_vlan_code.patch
deleted file mode 100644
index 9ceda4aa0a..0000000000
--- a/package/madwifi/patches/478-remove_vlan_code.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/net80211/ieee80211_input.c
-+++ b/net80211/ieee80211_input.c
-@@ -1223,6 +1223,7 @@ ieee80211_deliver_data(struct ieee80211_
- #endif
- 		vap->iv_devstats.rx_packets++;
- 		vap->iv_devstats.rx_bytes += skb->len;
-+#if IEEE80211_VLAN_TAG_USED
- 		if (ni->ni_vlan != 0 && vap->iv_vlgrp != NULL) {
- 			/* attach vlan tag */
- 			struct ieee80211_node *ni_tmp = SKB_CB(skb)->ni;
-@@ -1236,7 +1237,9 @@ ieee80211_deliver_data(struct ieee80211_
- 				vap->iv_devstats.rx_dropped++;
- 			}
- 			skb = NULL; /* SKB is no longer ours */
--		} else {
-+		} else
-+#endif
-+		{
- 			struct ieee80211_node *ni_tmp = SKB_CB(skb)->ni;
- 			if (netif_receive_skb(skb) == NET_RX_DROP) {
- 				/* If netif_receive_skb dropped the packet because
diff --git a/package/ps3-utils/Makefile b/package/ps3-utils/Makefile
deleted file mode 100644
index 3d3ea1befe..0000000000
--- a/package/ps3-utils/Makefile
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# Copyright (C) 2008-2010 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=ps3-utils
-PKG_REV:=6488134e48cf2d6f2d6471ced8346ac8cb1b855a
-PKG_VERSION:=20090320
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=git://git.kernel.org/pub/scm/linux/kernel/git/geoff/ps3-utils.git
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=$(PKG_REV)
-
-PKG_FIXUP:=autoreconf
-PKG_INSTALL=1
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/ps3-utils
-	SECTION:=utils
-	CATEGORY:=Utilities
-	TITLE:=PS3 Linux Utilities
-	URL:=http://kernel.org/pub/linux/kernel/people/geoff/cell/ps3-utils/
-	MAINTAINER:=Geoff Levand <geoffrey.levand@am.sony.com>
-	DEPENDS:=@TARGET_ps3||TARGET_ps3chk||TARGET_powerpc
-endef
-
-define Package/ps3-utils/description
-     The ps3-utils package is a set of system administration utilites for the
-     PS3 game console.
-endef
-
-define Build/Configure
-	(cd $(PKG_BUILD_DIR) && $(BASH) -x ./bootstrap)
-	$(call Build/Configure/Default)
-endef
-
-define Build/InstallDev
-	$(INSTALL_DIR) $(1)/usr/include
-	$(INSTALL_DATA) \
-		$(PKG_INSTALL_DIR)/usr/include/ps3*.h \
-		$(1)/usr/include
-
-	$(INSTALL_DIR) $(1)/usr/lib
-	$(INSTALL_BIN) \
-		$(PKG_INSTALL_DIR)/usr/lib/libps3-utils.{la,a,so*} \
-		$(1)/usr/lib/
-endef
-
-define Package/ps3-utils/install
-	$(INSTALL_DIR) $(1)/usr/sbin
-	$(INSTALL_DIR) $(1)/usr/bin
-	$(INSTALL_DIR) $(1)/usr/lib
-
-	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ps3-boot-game-os $(1)/usr/sbin
-	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ps3-dump-bootloader $(1)/usr/sbin
-	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ps3-flash-util $(1)/usr/sbin
-	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ps3-video-mode $(1)/usr/bin
-
-	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libps3-utils.so.* $(1)/usr/lib
-endef
-
-$(eval $(call BuildPackage,ps3-utils))
diff --git a/package/redboot-ar231x/Makefile b/package/redboot-ar231x/Makefile
deleted file mode 100644
index b07b5a3d2d..0000000000
--- a/package/redboot-ar231x/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# Copyright (C) 2008 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=redboot-ar231x
-PKG_VERSION:=2010-10-26
-PKG_RELEASE=$(PKG_SOURCE_VERSION)
-
-PKG_TARGETS:=bin
-
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL:=git://nbd.name/redboot-ar231x.git
-PKG_SOURCE_VERSION:=327f02ce1645d3427f26cf8116353332c81564a9
-PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.bz2
-
-include $(INCLUDE_DIR)/package.mk
-
-export GCC_HONOUR_COPTS=s
-
-define Package/redboot-ar231x
-  SECTION:=boot
-  CATEGORY:=Boot Loaders
-  DEPENDS:=@TARGET_atheros @BROKEN
-  TITLE:=Tiny redboot for AR231x/AR531x
-endef
-
-define Build/Configure
-	mkdir -p $(PKG_BUILD_DIR)/host-build
-	if [ \! -x $(PKG_BUILD_DIR)/host-install/bin/ecosconfig ]; then ( \
-		cd $(PKG_BUILD_DIR)/host-build; \
-		../ecos/host/configure \
-			--prefix=$(PKG_BUILD_DIR)/host-install \
-			--exec-prefix=$(PKG_BUILD_DIR)/host-install; \
-		CFLAGS="$(HOST_CFLAGS)" $(MAKE) all install; \
-	) fi
-endef
-
-define Build/Compile
-	$(MAKE) -C $(PKG_BUILD_DIR) all
-endef
-
-define Package/redboot-ar231x/install
-	$(CP) $(PKG_BUILD_DIR)/bin/* $(1)/
-endef
-
-$(eval $(call BuildPackage,redboot-ar231x))
diff --git a/package/redboot-ar231x/patches/010-fix-compile.patch b/package/redboot-ar231x/patches/010-fix-compile.patch
deleted file mode 100644
index f7c6e97457..0000000000
--- a/package/redboot-ar231x/patches/010-fix-compile.patch
+++ /dev/null
@@ -1,181 +0,0 @@
---- a/ecos/packages/hal/mips/ap30/current/cdl/hal_mips_ap30.cdl
-+++ b/ecos/packages/hal/mips/ap30/current/cdl/hal_mips_ap30.cdl
-@@ -98,7 +98,7 @@ cdl_package CYGPKG_HAL_MIPS_AP30 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/ap43/current/cdl/hal_mips_ap43.cdl
-+++ b/ecos/packages/hal/mips/ap43/current/cdl/hal_mips_ap43.cdl
-@@ -98,7 +98,7 @@ cdl_package CYGPKG_HAL_MIPS_AP43 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/ap48/current/cdl/hal_mips_ap48.cdl
-+++ b/ecos/packages/hal/mips/ap48/current/cdl/hal_mips_ap48.cdl
-@@ -98,7 +98,7 @@ cdl_package CYGPKG_HAL_MIPS_AP48 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/ap51/current/cdl/hal_mips_ap51.cdl
-+++ b/ecos/packages/hal/mips/ap51/current/cdl/hal_mips_ap51.cdl
-@@ -93,7 +93,7 @@ cdl_package CYGPKG_HAL_MIPS_AP51 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/ap53/current/cdl/hal_mips_ap53.cdl
-+++ b/ecos/packages/hal/mips/ap53/current/cdl/hal_mips_ap53.cdl
-@@ -93,7 +93,7 @@ cdl_package CYGPKG_HAL_MIPS_AP53 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/ap61/current/cdl/hal_mips_ap61.cdl
-+++ b/ecos/packages/hal/mips/ap61/current/cdl/hal_mips_ap61.cdl
-@@ -93,7 +93,7 @@ cdl_package CYGPKG_HAL_MIPS_AP61 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/ap65/current/cdl/hal_mips_ap65.cdl
-+++ b/ecos/packages/hal/mips/ap65/current/cdl/hal_mips_ap65.cdl
-@@ -93,7 +93,7 @@ cdl_package CYGPKG_HAL_MIPS_AP65 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/pb32/current/cdl/hal_mips_pb32.cdl
-+++ b/ecos/packages/hal/mips/pb32/current/cdl/hal_mips_pb32.cdl
-@@ -91,7 +91,7 @@ cdl_package CYGPKG_HAL_MIPS_PB32 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/pb44/current/cdl/hal_mips_pb44.cdl
-+++ b/ecos/packages/hal/mips/pb44/current/cdl/hal_mips_pb44.cdl
-@@ -99,7 +99,7 @@ cdl_package CYGPKG_HAL_MIPS_PB44 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/pb45/current/cdl/hal_mips_pb45.cdl
-+++ b/ecos/packages/hal/mips/pb45/current/cdl/hal_mips_pb45.cdl
-@@ -99,7 +99,7 @@ cdl_package CYGPKG_HAL_MIPS_PB45 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/packages/hal/mips/tb225/current/cdl/hal_mips_tb225.cdl
-+++ b/ecos/packages/hal/mips/tb225/current/cdl/hal_mips_tb225.cdl
-@@ -99,7 +99,7 @@ cdl_package CYGPKG_HAL_MIPS_TB225 {
-         $(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,plf_defs.tmp -o plf_mk_defs.tmp -S $<
-         fgrep .equ plf_mk_defs.tmp | sed s/#// > $@
-         @echo $@ ": \\" > $(notdir $@).deps
--        @tail +2 plf_defs.tmp >> $(notdir $@).deps
-+        @tail -n +2 plf_defs.tmp >> $(notdir $@).deps
-         @echo >> $(notdir $@).deps
-         @rm plf_defs.tmp plf_mk_defs.tmp
-     }
---- a/ecos/host/tools/configtool/standalone/common/cdl_exec.cxx
-+++ b/ecos/host/tools/configtool/standalone/common/cdl_exec.cxx
-@@ -51,6 +51,7 @@
- #endif
- #include "build.hxx"
- #include "cdl_exec.hxx"
-+#include <linux/limits.h>
- 
- // ----------------------------------------------------------------------------
- bool cdl_exec::quiet            = false;
---- a/ecos/host/tools/configtool/standalone/common/ecosconfig.cxx
-+++ b/ecos/host/tools/configtool/standalone/common/ecosconfig.cxx
-@@ -50,6 +50,7 @@
- #endif
- #include "cdl_exec.hxx"
- #include "ecosconfig.hxx"
-+#include <cstring>
- 
- #define TOOL_VERSION "2.net"
- #define TOOL_COPYRIGHT "Copyright (c) 2002 Red Hat, Inc."
---- a/ecos/host/libcdl/build.cxx
-+++ b/ecos/host/libcdl/build.cxx
-@@ -57,6 +57,7 @@
- // It implicitly supplies <string>, <vector> and <map> because
- // the class definitions rely on these headers.
- #include <cdlcore.hxx>
-+#include <cstring>
- 
- //}}}
- 
---- a/ecos/host/libcdl/parse.cxx
-+++ b/ecos/host/libcdl/parse.cxx
-@@ -58,6 +58,7 @@
- // It implicitly supplies <string>, <vector> and <map> because
- // the class definitions rely on these headers.
- #include <cdlcore.hxx>
-+#include <cstring> 
- 
- //}}}
- 
---- a/ecos/host/libcdl/cdlmisc.cxx
-+++ b/ecos/host/libcdl/cdlmisc.cxx
-@@ -66,6 +66,7 @@
- 
- // For access to strtod()
- #include <cstdlib>
-+#include <cstring> 
- 
- // strtod() involves errno...
- #include <cerrno>
---- a/ecos/host/infra/assert.cxx
-+++ b/ecos/host/infra/assert.cxx
-@@ -61,6 +61,7 @@
- // STDLIB is needed for exit() and the status codes.
- #include <cstdio>
- #include <cstdlib>
-+#include <cstring>
- 
- #if defined(__unix__) || defined(__CYGWIN32__)
- extern "C" {
diff --git a/package/siit/Makefile b/package/siit/Makefile
deleted file mode 100644
index 4cd147f77b..0000000000
--- a/package/siit/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-# 
-# Copyright (C) 2006-2010 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=siit
-PKG_VERSION:=1.1
-PKG_RELEASE:=2
-
-include $(INCLUDE_DIR)/package.mk
-
-define KernelPackage/siit
-  SUBMENU:=Network Devices
-  TITLE:=Stateless IP ICMP Translation Algorithm
-  DEPENDS:= @(!(TARGET_ps3||TARGET_pxcab)||BROKEN)
-  FILES:=$(PKG_BUILD_DIR)/siit.ko
-  AUTOLOAD:=$(call AutoLoad,50,siit)
-endef
-
-include $(INCLUDE_DIR)/kernel-defaults.mk
-
-define KernelPackage/siit/description
- Stateless IP ICMP Translation Algorithm
-endef
-
-define Build/Prepare
-	mkdir -p $(PKG_BUILD_DIR)
-	cp src/Makefile src/siit.h src/siit.c $(PKG_BUILD_DIR)/
-endef
-
-define Build/Compile
-	$(MAKE) $(KERNEL_MAKEOPTS) SUBDIRS="$(PKG_BUILD_DIR)" modules
-endef
-
-$(eval $(call KernelPackage,siit))
diff --git a/package/siit/src/Makefile b/package/siit/src/Makefile
deleted file mode 100644
index 06c36f1e3a..0000000000
--- a/package/siit/src/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-obj-m   := siit.o
-ifeq ($(MAKING_MODULES),1)
--include $(TOPDIR)/Rules.make
-endif
-
diff --git a/package/siit/src/siit.c b/package/siit/src/siit.c
deleted file mode 100644
index 5362c1daae..0000000000
--- a/package/siit/src/siit.c
+++ /dev/null
@@ -1,1478 +0,0 @@
-/*
- * siit.c: the Stateless IP/ICMP Translator (SIIT) module for Linux.
- *
- *
- */
-
-#include <linux/version.h>
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
-#include <generated/autoconf.h>
-#else
-#include <linux/autoconf.h>
-#endif
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>       /* printk() */
-#include <linux/slab.h>
-
-#include <linux/errno.h>        /* error codes */
-#include <linux/types.h>        /* size_t */
-#include <linux/interrupt.h>    /* mark_bh */
-#include <linux/random.h>
-#include <linux/in.h>
-#include <linux/netdevice.h>    /* struct device, and other headers */
-#include <linux/etherdevice.h>  /* eth_type_trans */
-#include <net/ip.h>             /* struct iphdr */
-#include <net/icmp.h>           /* struct icmphdr */
-#include <net/ipv6.h>
-#include <net/udp.h>
-#include <linux/skbuff.h>
-#include <linux/in6.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/checksum.h>
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
-#include <net/ip6_checksum.h>
-#endif
-#include <linux/in6.h>
-#include "siit.h"
-
-MODULE_AUTHOR("Dmitriy Moscalev, Grigory Klyuchnikov, Felix Fietkau");
-
-/*
- * If tos_ignore_flag != 0, we don't copy TOS and Traffic Class
- * from origin paket and set it to 0
- */
-int tos_ignore_flag = 0;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static inline void
-skb_reset_mac_header(struct sk_buff *skb)
-{
-	skb->mac.raw=skb->data;
-}
-
-static struct net_device_stats *
-siit_get_stats(struct net_device *dev)
-{
-	return netdev_priv(dev);
-}
-
-static inline void random_ether_addr(u8 *addr)
-{
-	get_random_bytes (addr, ETH_ALEN);
-	addr [0] &= 0xfe;	/* clear multicast bit */
-	addr [0] |= 0x02;	/* set local assignment bit (IEEE802) */
-}
-
-
-#define siit_stats(_dev) ((struct net_device_stats *)netdev_priv(_dev))
-#else
-#define siit_stats(_dev) (&(_dev)->stats)
-#endif
-
-/*
- * The Utility  stuff
- */
-
-#ifdef SIIT_DEBUG
-/* print dump bytes (data point data area sizeof len and message
- * before dump.
- */
-static int siit_print_dump(char *data, int len, char *message)
-{
-	int i;
-	int j = 0, k = 1;
-
-	len = len > BUFF_SIZE ? BUFF_SIZE : len;
-	printk("%s:\n", message);
-	for (i=0; i < len; i++, k++) {
-		if( i == len-1 || k == 16) {
-			printk("%02x\n", (~(~0 << 8) & *(data+i)));
-			j = 0;
-			k = 0;
-		}
-		else if (j) {
-			printk("%02x ", (~(~0 << 8) & *(data+i)));
-			j--;
-		}
-		else {
-			printk("%02x", (~(~0 << 8) & *(data+i)));
-			j++;
-		}
-	}
-	return 0;
-}
-#endif
-
-/*
- * Open and close
- */
-static int siit_open(struct net_device *dev)
-{
-	netif_start_queue(dev);
-	return 0;
-}
-
-
-static int siit_release(struct net_device *dev)
-{
-	netif_stop_queue(dev); /* can't transmit any more */
-	return 0;
-}
-
-/*
- * Translation IPv4 to IPv6 stuff
- *
- * ip4_ip6 (src, len, dst, include_flag)
- *
- * where
- * src - buffer with original IPv4 packet,
- * len - size of original packet,
- * dst - new buffer for IPv6 packet,
- * include_flag - if = 1, dst point to IPv4 packet that is ICMP error
- *                included IP packet, else = 0
- */
-
-static int ip4_ip6(char *src, int len, char *dst, int include_flag)
-{
-	struct iphdr *ih4 = (struct iphdr *) src; /* point to current IPv4 header struct */
-	struct icmphdr *icmp_hdr;   /* point to current ICMPv4 header struct */
-	struct udphdr *udp_hdr;     /* point to current IPv4 UDP header struct */
-
-	struct ipv6hdr *ih6 = (struct ipv6hdr *) dst; /* point to current IPv6 header struct */
-	struct frag_hdr *ih6_frag = (struct frag_hdr *)(dst+sizeof(struct ipv6hdr));
-										      /* point to current IPv6 fragment header struct */
-	struct icmp6hdr *icmp6_hdr; /* point to current ICMPv6 header */
-
-	int hdr_len = (int)(ih4->ihl * 4); /* IPv4 header length */
-	int icmp_len;               /* ICMPv4 packet length */
-	int plen;                   /* payload length */
-
-	unsigned int csum;          /* need to calculate ICMPv6 and UDP checksum */
-	int fl_csum = 0;            /* flag to calculate UDP checksum */
-	int icmperr = 1;            /* flag to indicate ICMP error message and to need
-								   translate ICMP included IP packet */
-	int fr_flag = 0;            /* fragment flag, if = 0 - don't add
-								   fragment header */
-	__u16 new_tot_len;          /* need to calculate IPv6 total length */
-	__u8 new_nexthdr;           /* next header code */
-	__u16 icmp_ptr = 0;         /* Pointer field in ICMP_PARAMETERPROB */
-
-#ifdef SIIT_DEBUG              /* print IPv4 header dump */
-	siit_print_dump(src, hdr_len, "siit: ip4_ip6() (in) ip4 header dump");
-#endif
-
-	/* If DF == 1 && MF == 0 && Fragment Offset == 0
-	 * or this packet is ICMP included IP packet
-	 * we don't need fragment header */
-	if (ntohs(ih4->frag_off) == IP_DF || include_flag ) {
-		/* not fragment and we need not to add Fragment
-		 * Header to IPv6 packet. */
-		/* total length = total length from IPv4 packet */
-		new_tot_len = ntohs(ih4->tot_len);
-
-		if (ih4->protocol == IPPROTO_ICMP)
-			new_nexthdr = NEXTHDR_ICMP;
-		else
-			new_nexthdr = ih4->protocol;
-	}
-	else {
-		/* need to add Fragment Header */
-		fr_flag = 1;
-		/* total length = total length from IPv4 packet +
-		   length of Fragment Header */
-		new_tot_len = ntohs(ih4->tot_len) + sizeof(struct frag_hdr);
-		/* IPv6 Header NextHeader = NEXTHDR_FRAGMENT */
-		new_nexthdr = NEXTHDR_FRAGMENT;
-		/* Fragment Header NextHeader copy from IPv4 packet */
-		if (ih4->protocol == IPPROTO_ICMP)
-			ih6_frag->nexthdr = NEXTHDR_ICMP;
-		else
-			ih6_frag->nexthdr = ih4->protocol;
-
-		/* copy frag offset from IPv4 packet */
-		ih6_frag->frag_off = htons((ntohs(ih4->frag_off) & IP_OFFSET) << 3);
-		/* copy MF flag from IPv4 packet */
-		ih6_frag->frag_off = htons((ntohs(ih6_frag->frag_off) |
-									((ntohs(ih4->frag_off) & IP_MF) >> 13)));
-		/* copy Identification field from IPv4 packet */
-		ih6_frag->identification = htonl(ntohs(ih4->id));
-		/* reserved field initialized to zero */
-		ih6_frag->reserved = 0;
-	}
-
-	/* Form rest IPv6 fields */
-
-	/*
-	 * At this point we need to add checking of unxpired source
-	 * route optin and if it is, send ICMPv4 "destination
-	 * unreacheble/source route failes" Type 3/Code 5 and
-	 * drop packet. (NOT RELEASED YET)
-	 */
-
-	/* IP version = 6 */
-	ih6->version = 6;
-
-	if (tos_ignore_flag) {
-		ih6->priority = 0;
-		ih6->flow_lbl[0] = 0;
-	} else {
-		ih6->priority = (ih4->tos & 0xf0) >> 4;
-		ih6->flow_lbl[0] = (ih4->tos & 0x0f) << 4;
-	}
-	ih6->flow_lbl[1] = 0;
-	ih6->flow_lbl[2] = 0;
-
-	/* Hop Limit = IPv4 TTL */
-	ih6->hop_limit = ih4->ttl;
-
-	/* Translate source destination addresses,
-	   for IPv6 host it's IPv4-translated IPv6 address,
-	   for IPv4 host it's IPv4-mapped IPv6 address
-
-	   !!WARNING!! Instead IPv4-mapped IPv6 addresses we use addreesses
-	   with unused prefix ::ffff:ffff:0:0/96, because KAME implementation
-	   doesn't support IPv4-mapped addresses in IPv6 packets and discard them.
-
-	*/
-
-	if (include_flag) {
-		/*
-		   It's ICMP included IP packet and there is a diffirence
-		   in src/dst addresses then src/dst in normal direction
-		 */
-
-		/*
-		   Source address
-		   is IPv4-translated IPv6 address because packet traveled
-		   from IPv6 to IPv4 area
-		*/
-		ih6->saddr.in6_u.u6_addr32[0] = 0;
-		ih6->saddr.in6_u.u6_addr32[1] = 0;
-		ih6->saddr.in6_u.u6_addr32[2] = htonl(TRANSLATED_PREFIX); /* to network order bytes */
-		ih6->saddr.in6_u.u6_addr32[3] = ih4->saddr;
-
-		/*
-		   Destination address
-		   is IPv4-mapped address (but it's not IPv4- mapped, we use
-		   prefix ::ffff:ffff:0:0/96
-		 */
-		ih6->daddr.in6_u.u6_addr32[0] = 0;
-		ih6->daddr.in6_u.u6_addr32[1] = 0;
-		ih6->daddr.in6_u.u6_addr32[2] = htonl(MAPPED_PREFIX); /* to network order bytes */
-		ih6->daddr.in6_u.u6_addr32[3] = ih4->daddr;
-	}
-	else {
-
-		/*
-		   This is normal case (packet isn't included IP packet)
-
-		   Source address
-		   is IPv4-mapped address (but it's not IPv4- mapped, we use
-		   prefix ::ffff:ffff:0:0/96)
-		*/
-		ih6->saddr.in6_u.u6_addr32[0] = 0;
-		ih6->saddr.in6_u.u6_addr32[1] = 0;
-		ih6->saddr.in6_u.u6_addr32[2] = htonl(MAPPED_PREFIX); /* to network order bytes */
-		ih6->saddr.in6_u.u6_addr32[3] = ih4->saddr;
-
-		/* Destination address
-		   is is IPv4-translated IPv6 address
-		 */
-		ih6->daddr.in6_u.u6_addr32[0] = 0;
-		ih6->daddr.in6_u.u6_addr32[1] = 0;
-		ih6->daddr.in6_u.u6_addr32[2] = htonl(TRANSLATED_PREFIX); /* to network order bytes */
-		ih6->daddr.in6_u.u6_addr32[3] = ih4->daddr;
-	}
-
-	/* Payload Length */
-	plen = new_tot_len - hdr_len; /* Payload length = IPv4 total len - IPv4 header len */
-	ih6->payload_len = htons(plen);
-
-	/* Next Header */
-	ih6->nexthdr = new_nexthdr; /* Next Header */
-
-	/* Process ICMP protocols data */
-
-	switch (ih4->protocol) {
-	case IPPROTO_ICMP:
-		if ( (ntohs(ih4->frag_off) & IP_OFFSET) != 0 || (ntohs(ih4->frag_off) & IP_MF) != 0 ) {
-			PDEBUG("ip4_ip6(): don't translate ICMPv4 fragments - packet dropped.\n");
-			return -1;
-		}
-
-		icmp_hdr = (struct icmphdr *) (src+hdr_len); /* point to ICMPv4 header */
-		csum = 0;
-		icmp_len =  ntohs(ih4->tot_len) - hdr_len; /* ICMPv4 packet length */
-		icmp6_hdr = (struct icmp6hdr *)(dst+sizeof(struct ipv6hdr)
-									    +fr_flag*sizeof(struct frag_hdr)); /* point to ICMPv6 header */
-
-		if (include_flag) {
-			/* ICMPv4 packet cannot be included in ICMPv4 Error message */
-			/* !!! May be it's WRONG !!! ICMPv4 QUERY packet can be included
-			   in ICMPv4 Error message */
-			PDEBUG("ip4_ip6(): It's included ICMPv4 in ICMPv4 Error message - packet dropped.\n");
-			return -1;
-		}
-
-		/* Check ICMPv4 Type field */
-		switch (icmp_hdr->type) {
-		/* ICMP Error messages */
-		/* Destination Unreachable (Type 3) */
-		case ICMP_DEST_UNREACH:
-			icmp6_hdr->icmp6_type = ICMPV6_DEST_UNREACH; /* to Type 1 */
-			icmp6_hdr->icmp6_unused = 0;
-			switch (icmp_hdr->code)
-			{
-			case ICMP_NET_UNREACH: /* Code 0 */
-			case ICMP_HOST_UNREACH: /* Code 1 */
-			case ICMP_SR_FAILED: /* Code 5 */
-			case ICMP_NET_UNKNOWN: /* Code 6 */
-			case ICMP_HOST_UNKNOWN: /* Code 7 */
-			case ICMP_HOST_ISOLATED: /* Code 8 */
-			case ICMP_NET_UNR_TOS: /* Code 11 */
-			case ICMP_HOST_UNR_TOS: /* Code 12 */
-				icmp6_hdr->icmp6_code = ICMPV6_NOROUTE; /* to Code 0 */
-				break;
-			case ICMP_PROT_UNREACH: /* Code 2 */
-				icmp6_hdr->icmp6_type = ICMPV6_PARAMPROB; /* to Type 4 */
-				icmp6_hdr->icmp6_code = ICMPV6_UNK_NEXTHDR; /* to Code 1 */
-				/* Set pointer filed to 6, it's octet offset IPv6 Next Header field */
-				icmp6_hdr->icmp6_pointer = htonl(6);
-				break;
-			case ICMP_PORT_UNREACH: /* Code 3 */
-				icmp6_hdr->icmp6_code = ICMPV6_PORT_UNREACH; /* to Code 4 */
-				break;
-			case ICMP_FRAG_NEEDED: /* Code 4 */
-				icmp6_hdr->icmp6_type = ICMPV6_PKT_TOOBIG; /* to Type 2 */
-				icmp6_hdr->icmp6_code = 0;
-				/* Correct MTU  */
-				if (icmp_hdr->un.frag.mtu == 0)
-					/* we use minimum MTU for IPv4 PMTUv4 RFC1191, section 5;
-					   IPv6 implementation wouldn't accept Path MTU < 1280,
-					   but it records info correctly to always include
-					   a fragment header */
-					icmp6_hdr->icmp6_mtu = htonl(576);
-				else
-					/* needs to adjusted for difference between IPv4/IPv6 headers
-					 * SIIT RFC2765, section 3.3,
-					 * we assume that difference is 20 bytes */
-					icmp6_hdr->icmp6_mtu = htonl(ntohs(icmp_hdr->un.frag.mtu)+IP4_IP6_HDR_DIFF);
-
-				break;
-			case ICMP_NET_ANO: /* Code 9 */
-			case ICMP_HOST_ANO: /* Code 10 */
-				icmp6_hdr->icmp6_code = ICMPV6_ADM_PROHIBITED; /* to Code 1 */
-				break;
-			default: /* discard any other Code */
-				PDEBUG("ip4_ip6(): Unknown ICMPv4 Type %d Code %d - packet dropped.\n",
-					   ICMP_DEST_UNREACH, icmp_hdr->code);
-				return -1;
-			}
-			break;
-			/* Time Exceeded (Type 11) */
-		case ICMP_TIME_EXCEEDED:
-			icmp6_hdr->icmp6_type = ICMPV6_TIME_EXCEED;
-			icmp6_hdr->icmp6_code = icmp_hdr->code;
-			break;
-			/* Parameter Problem (Type 12) */
-		case ICMP_PARAMETERPROB:
-			icmp6_hdr->icmp6_type = ICMPV6_PARAMPROB;
-			icmp6_hdr->icmp6_code = icmp_hdr->code;
-
-			icmp_ptr = ntohs(icmp_hdr->un.echo.id) >> 8;
-			switch (icmp_ptr) {
-			case 0:
-				icmp6_hdr->icmp6_pointer = 0; /* IPv4 Version -> IPv6 Version */
-				break;
-			case 2:
-				icmp6_hdr->icmp6_pointer = __constant_htonl(4); /* IPv4 length -> IPv6 Payload Length */
-				break;
-			case 8:
-				icmp6_hdr->icmp6_pointer = __constant_htonl(7); /* IPv4 TTL -> IPv6 Hop Limit */
-				break;
-			case 9:
-				icmp6_hdr->icmp6_pointer = __constant_htonl(6); /* IPv4 Protocol -> IPv6 Next Header */
-				break;
-			case 12:
-				icmp6_hdr->icmp6_pointer = __constant_htonl(8); /* IPv4 Src Addr -> IPv6 Src Addr */
-				break;
-			case 16:
-				icmp6_hdr->icmp6_pointer = __constant_htonl(24); /* IPv4 Dst Addr -> IPv6 Dst Addr */
-				break;
-			default:
-				icmp6_hdr->icmp6_pointer = 0xffffffff; /* set to all ones in any other cases */
-				break;
-			}
-			break;
-		case ICMP_ECHO:
-			icmperr = 0;
-			icmp6_hdr->icmp6_type = ICMPV6_ECHO_REQUEST;
-			icmp6_hdr->icmp6_code = 0;
-			/* Copy rest ICMP data to new IPv6 packet without changing */
-			memcpy(((char *)icmp6_hdr)+4, ((char *)icmp_hdr)+4, len - hdr_len - 4);
-			break;
-
-		case ICMP_ECHOREPLY:
-			icmperr = 0;
-			icmp6_hdr->icmp6_type = ICMPV6_ECHO_REPLY;
-			icmp6_hdr->icmp6_code = 0;
-			/* Copy rest ICMP data to new IPv6 packet without changing */
-			memcpy(((char *)icmp6_hdr)+4, ((char *)icmp_hdr)+4, len - hdr_len - 4);
-			break;
-
-			/* Discard any other ICMP messages */
-		default:
-			PDEBUG("ip4_ip6(): Unknown ICMPv4 packet Type %x - packet dropped.\n", icmp_hdr->type);
-			return -1;
-		}
-
-		/* Now if it's ICMPv4 Error message we must translate included IP packet */
-
-		if (icmperr) {
-			/* Call our ip4_ip6() to translate included IP packet */
-			if (ip4_ip6(src+hdr_len+sizeof(struct icmphdr), len - hdr_len - sizeof(struct icmphdr),
-						dst+sizeof(struct ipv6hdr)+fr_flag*sizeof(struct frag_hdr)
-						+sizeof(struct icmp6hdr), 1) == -1) {
-				PDEBUG("ip4_ip6(): Uncorrect translation of ICMPv4 Error message - packet dropped.\n");
-				return -1;
-			}
-			/* correct ICMPv6 packet length for diffirence between IPv4 and IPv6 headers
-			   in included IP packet
-			   */
-			icmp_len += 20;
-			/* and correct Payload length for diffirence between IPv4 and IPv6 headers */
-			plen += 20;
-			ih6->payload_len = htons(plen);
-		}
-
-		/* Calculate ICMPv6 checksum */
-
-		icmp6_hdr->icmp6_cksum = 0;
-		csum = 0;
-
-		csum = csum_partial((u_char *)icmp6_hdr, icmp_len, csum);
-		icmp6_hdr->icmp6_cksum = csum_ipv6_magic(&ih6->saddr, &ih6->daddr, icmp_len,
-									         IPPROTO_ICMPV6, csum);
-		break;
-
-	/* Process TCP protocols data */
-	case IPPROTO_TCP:
-		/* Copy TCP data to new IPv6 packet without changing */
-		memcpy(dst+sizeof(struct ipv6hdr)+fr_flag*sizeof(struct frag_hdr),
-				   src+hdr_len, len - hdr_len);
-		break;
-
-	/* Process UDP protocols data */
-	case IPPROTO_UDP:
-		udp_hdr = (struct udphdr *)(src+hdr_len);
-		if ((ntohs(ih4->frag_off) & IP_OFFSET) == 0) {
-			if ((ntohs(ih4->frag_off) & IP_MF) != 0) {
-				/* It's a first fragment */
-				if (udp_hdr->check == 0) {
-					/* System management event */
-					printk("siit: First fragment of UDP with zero checksum - packet droped\n");
-					printk("siit: addr: %x src port: %d dst port: %d\n",
-						   htonl(ih4->saddr), htons(udp_hdr->source), htons(udp_hdr->dest));
-					return -1;
-				}
-			}
-			else if (udp_hdr->check == 0)
-				fl_csum = 1;
-		}
-
-		/* Copy UDP data to new IPv6 packet */
-		udp_hdr = (struct udphdr *)(dst+sizeof(struct ipv6hdr)
-									+ fr_flag*sizeof(struct frag_hdr));
-		memcpy((char *)udp_hdr, src+hdr_len, len - hdr_len);
-
-		/* Calculate UDP checksum if UDP checksum in IPv4 packet was ZERO
-		   and if it isn't included IP packet
-		 */
-		if (fl_csum && (!include_flag)) {
-			udp_hdr->check = 0;
-			csum = 0;
-			csum = csum_partial((unsigned char *)udp_hdr, plen - fr_flag*sizeof(struct frag_hdr), csum);
-			udp_hdr->check = csum_ipv6_magic(&ih6->saddr, &ih6->daddr, plen -
-										     fr_flag*sizeof(struct frag_hdr), IPPROTO_UDP, csum);
-		}
-		break;
-
-	/* Discard packets with any other protocol */
-	default:
-		PDEBUG("ip4_ip6(): Unknown upper protocol - packet dropped.\n");
-		return -1;
-	}
-
-#ifdef SIIT_DEBUG
-	siit_print_dump(dst, sizeof(struct ipv6hdr), "siit: ip4_ip6(): (out) ipv6 header dump");
-#endif
-
-	return 0;
-}
-
-/*
- * Translation IPv6 to IPv4 stuff
- *
- * ip6_ip4(src, len, dst, include_flag)
- *
- * where
- * src - buffer with original IPv6 packet,
- * len - size of original packet,
- * dst - new buffer for IPv4 packet,
- * include_flag - if = 1, dst point to IPv6 packet that is ICMP error
- *                included IP packet, else = 0
- *
- */
-
-static int ip6_ip4(char *src, int len, char *dst, int include_flag)
-{
-	struct ipv6hdr *ip6_hdr;    /* point to current IPv6 header struct */
-	struct iphdr *ip_hdr;       /* point to current IPv4 header struct */
-	int opts_len = 0;           /* to sum Option Headers length */
-	int icmperr = 1;            /* if = 1, indicate that packet is ICMP Error message, else = 0 */
-	int ntot_len = 0;           /* to calculate IPv6 Total Length field */
-	int real_len;
-	int len_delta;
-	int ip6_payload_len;
-	int inc_opts_len = 0;       /* to sum Option Headers length in ICMP included IP packet */
-	__u8 next_hdr;              /* Next Header */
-
-#ifdef SIIT_DEBUG
-	siit_print_dump(src, sizeof(struct ipv6hdr), "siit: ip6_ip4(): (in) ipv6 header dump");
-#endif
-
-	if ( (len_delta = len - sizeof(struct ipv6hdr)) >= 0)
-	{
-		ip6_hdr = (struct ipv6hdr *)src;
-		ip_hdr = (struct iphdr *)dst;
-
-		real_len = sizeof(struct iphdr);
-
-		/* Check validation of Saddr & Daddr? is a packet to fall under our translation? */
-		if (include_flag) { /* It's ICMP included IP packet,
-							   about process include_flag see comment in ip4_ip6() */
-			if (ip6_hdr->saddr.s6_addr32[2] != htonl(MAPPED_PREFIX)) {
-				PDEBUG("ip6_ip4(): Included IP packet Src addr isn't mapped addr: %x%x%x%x, packet dropped.\n",
-					   ip6_hdr->saddr.s6_addr32[0], ip6_hdr->saddr.s6_addr32[1],
-					   ip6_hdr->saddr.s6_addr32[2], ip6_hdr->saddr.s6_addr32[3]);
-				return -1;
-			}
-			if ( ip6_hdr->daddr.s6_addr32[2] != htonl(TRANSLATED_PREFIX)) {
-				PDEBUG("ip6_ip4(): Included IP packet Dst addr isn't translated addr: %x%x%x%x, packet dropped.\n",
-					   ip6_hdr->daddr.s6_addr32[0], ip6_hdr->daddr.s6_addr32[1],
-					   ip6_hdr->daddr.s6_addr32[2], ip6_hdr->daddr.s6_addr32[3]);
-				return -1;
-			}
-		}
-		else { /* It's normal IP packet (not included in ICMP) */
-			if (ip6_hdr->saddr.s6_addr32[2] != htonl(TRANSLATED_PREFIX)) {
-				PDEBUG("ip6_ip4(): Src addr isn't translated addr: %x%x%x%x, packet dropped.\n",
-					   ip6_hdr->saddr.s6_addr32[0], ip6_hdr->saddr.s6_addr32[1],
-					   ip6_hdr->saddr.s6_addr32[2], ip6_hdr->saddr.s6_addr32[3]);
-				return -1;
-			}
-			if ( ip6_hdr->daddr.s6_addr32[2] != htonl(MAPPED_PREFIX)) {
-				PDEBUG("ip6_ip4(): Dst addr isn't mapped addr: %x%x%x%x, packet dropped.\n",
-					   ip6_hdr->daddr.s6_addr32[0], ip6_hdr->daddr.s6_addr32[1],
-					   ip6_hdr->daddr.s6_addr32[2], ip6_hdr->daddr.s6_addr32[3]);
-				return -1;
-			}
-		}
-
-		/* Set IPv4 Fragment Offset and ID to 0
-		   before process any Option Headers */
-		ip_hdr->frag_off = 0;
-		ip_hdr->id = 0;
-
-		/*
-		 * We process only Fragment Header. Any other options headers
-		 * are ignored, i.e. there is no attempt to translate them.
-		 * However, the Total Length field and the Protocol field would
-		 * have to be adjusted to "skip" these extension headers.
-		 */
-
-		next_hdr = ip6_hdr->nexthdr;
-
-		/* Hop_by_Hop options header (ip6_hdr->nexthdr = 0). It must
-		 * appear only in IPv6 header's Next Header field.
-		 */
-		if (next_hdr == NEXTHDR_HOP) {
-			if ( (len_delta - sizeof(struct ipv6_opt_hdr)) >= 0)
-			{
-				struct ipv6_opt_hdr *ip6h =
-					(struct ipv6_opt_hdr *)(src+sizeof(struct ipv6hdr) + opts_len);
-				if ( (len_delta -= ip6h->hdrlen*8 + 8) >= 0)
-				{
-					opts_len += ip6h->hdrlen*8 + 8;  /* See  RFC 2460 page 11:
-							Hdr Ext Len  8-bit unsigned integer.  Length of the Hop-by-
-										 Hop Options header in 8-octet units, not
-										 including the first 8 octets.
-							*/
-					next_hdr = ip6h->nexthdr;
-				}
-				else
-				{
-					PDEBUG("ip6_ip4(): hop_by_hop header error, packet droped");
-					/* Generate ICMP Parameter Problem */
-					return -1;
-				}
-			}
-		}
-
-		if (len_delta > 0)
-		{
-			while(next_hdr != NEXTHDR_ICMP && next_hdr != NEXTHDR_TCP
-				  && next_hdr != NEXTHDR_UDP)
-			{
-				/* Destination options header */
-				if (next_hdr == NEXTHDR_DEST)
-				{
-					if ( (len_delta - sizeof(struct ipv6_opt_hdr)) >= 0)
-					{
-						struct ipv6_opt_hdr *ip6d =
-							(struct ipv6_opt_hdr *)(src + sizeof(struct ipv6hdr) + opts_len);
-						if ( (len_delta -= ip6d->hdrlen*8 + 8) >= 0)
-						{
-							opts_len += ip6d->hdrlen*8 + 8;
-							next_hdr = ip6d->nexthdr;
-						}
-					}
-					else
-					{
-						PDEBUG("ip6_ip4(): destination header error, packet droped");
-						/* Generate ICMP Parameter Problem */
-						return -1;
-					}
-				}
-				/* Routing options header */
-				else if (next_hdr == NEXTHDR_ROUTING)
-				{
-					if ( (len_delta - sizeof(struct ipv6_rt_hdr)) >= 0)
-					{
-						struct ipv6_rt_hdr *ip6rt =
-							(struct ipv6_rt_hdr *)(src+sizeof(struct ipv6hdr) + opts_len);
-						/* RFC 2765 SIIT, 4.1:
-						   If a routing header with a non-zero Segments Left field is present
-						   then the packet MUST NOT be translated, and an ICMPv6 "parameter
-						   problem/ erroneous header field encountered" (Type 4/Code 0) error
-						   message, with the Pointer field indicating the first byte of the
-						   Segments Left field, SHOULD be returned to the sender.
-						   */
-						if (ip6rt->segments_left != 0) {
-							/* Build ICMPv6 "Parameter Problem/Erroneous Header
-							   Field Encountered" & drop the packet */
-							/* !!! We don't send ICMPv6 "Parameter Problem" !!! */
-							PDEBUG("ip6_ip4(): routing header type != 0\n");
-							return -1;
-						}
-						if ( (len_delta -= ip6rt->hdrlen*8 + 8) >= 0)
-						{
-							opts_len += ip6rt->hdrlen*8 + 8;
-							next_hdr = ip6rt->nexthdr;
-						}
-						else
-						{
-							PDEBUG("ip6_ip4(): routing header error, packet droped");
-							/* Generate ICMP Parameter Problem */
-							return -1;
-						}
-					}
-				}
-				/* Fragment options header */
-				else if (next_hdr == NEXTHDR_FRAGMENT)
-				{
-					if ( (len_delta -= sizeof(struct frag_hdr)) >= 0)
-					{
-						struct frag_hdr *ip6f =
-							(struct frag_hdr *)(src+sizeof(struct ipv6hdr)+opts_len);
-
-						opts_len += sizeof(struct frag_hdr);      /* Frag Header Length = 8 */
-						ip_hdr->id = htons(ntohl(ip6f->identification)); /* ID field */
-						ip_hdr->frag_off = htons((ntohs(ip6f->frag_off) & IP6F_OFF_MASK) >> 3);
-										                                   /* fragment offset */
-						ip_hdr->frag_off = htons(ntohs(ip_hdr->frag_off) |
-										         ((ntohs(ip6f->frag_off) & IP6F_MORE_FRAG) << 13));
-										                                  /* more fragments flag */
-						next_hdr = ip6f->nexthdr;
-					}
-					else
-					{
-						PDEBUG("ip6_ip4(): fragment header error, packet droped");
-						/* Generate ICMP Parameter Problem */
-						return -1;
-					}
-				}
-				/* No Next Header */
-				else if (next_hdr == NEXTHDR_NONE)
-				{
-					/* RFC 2460 IPv6 Specification, 4.7
-					   4.7 No Next Header
-
-					   The value 59 in the Next Header field of an IPv6 header or any
-					   extension header indicates that there is nothing following that
-					   header.  If the Payload Length field of the IPv6 header indicates the
-					   presence of octets past the end of a header whose Next Header field
-					   contains 59, those octets must be ignored, and passed on unchanged if
-					   the packet is forwarded.
-					   */
-					break;
-				}
-				else if (next_hdr == NEXTHDR_ESP || next_hdr == NEXTHDR_AUTH)
-				{
-					PDEBUG("ip6_ip4(): cannot translate AUTH or ESP extention header, packet dropped\n");
-					return -1;
-				}
-				else if (next_hdr == NEXTHDR_IPV6)
-				{
-					PDEBUG("ip6_ip4(): cannot translate IPv6-IPv6 packet, packet dropped\n");
-					return -1;
-				}
-				else if (next_hdr == 0)
-				{
-					/* As say RFC 2460 (IPv6 Spec) we should discard the packet and send an
-					   ICMP Parameter Problem message to the source of the packet, with an
-					   ICMP Code value of 1 ("unrecognized Next Header type encountered")
-					   and the ICMP Pointer field containing the offset of the unrecognized
-					   value within the original packet
-					   */
-					/* NOT IMPLEMENTED */
-					PDEBUG("ip6_ip4(): NEXTHDR in extention header = 0, packet dropped\n");
-					return -1;
-				}
-				else
-				{
-					PDEBUG("ip6_ip4(): cannot translate extention header = %d, packet dropped\n", next_hdr);
-					return -1;
-				}
-			}
-		}
-	}
-	else
-	{
-	   PDEBUG("ip6_ip4(): error packet len, packet dropped.\n");
-	   return -1;
-	}
-
-	/* Building ipv4 packet */
-
-	ip_hdr->version = IPVERSION;
-	ip_hdr->ihl = 5;
-
-	/* TOS see comment about TOS in ip4_ip6() */
-	if (tos_ignore_flag)
-		ip_hdr->tos = 0;
-	else {
-		ip_hdr->tos = ip6_hdr->priority << 4;
-		ip_hdr->tos = ip_hdr->tos | (ip6_hdr->flow_lbl[0] >> 4);
-	}
-
-	/* IPv4 Total Len = IPv6 Payload Len +
-	   IPv4 Header Len (without options) - Options Headers Len */
-	ip6_payload_len = ntohs(ip6_hdr->payload_len);
-
-	if (ip6_payload_len == 0)
-		ntot_len = 0;
-	else
-		ntot_len = ip6_payload_len + IP4_IP6_HDR_DIFF - opts_len;
-
-	ip_hdr->tot_len = htons(ntot_len);
-
-	/* IPv4 TTL = IPv6 Hop Limit */
-	ip_hdr->ttl = ip6_hdr->hop_limit;
-
-	/* IPv4 Protocol = Next Header that will point to upper layer protocol */
-	ip_hdr->protocol = next_hdr;
-
-	/* IPv4 Src addr = last 4 bytes from IPv6 Src addr */
-	ip_hdr->saddr = ip6_hdr->saddr.s6_addr32[3];
-	/* IPv4 Dst addr = last 4 bytes from IPv6 Dst addr */
-	ip_hdr->daddr = ip6_hdr->daddr.s6_addr32[3];
-
-	/* Calculate IPv4 header checksum */
-	ip_hdr->check = 0;
-	ip_hdr->check = ip_fast_csum((unsigned char *)ip_hdr, ip_hdr->ihl);
-
-	if (len_delta > 0)
-	{
-		/* PROCESS ICMP */
-
-		if (next_hdr == NEXTHDR_ICMP)
-		{
-			struct icmp6hdr *icmp6_hdr;
-			struct icmphdr *icmp_hdr;
-
-			if ((len_delta -= sizeof(struct icmp6hdr)) >= 0)
-			{
-				icmp6_hdr = (struct icmp6hdr *)(src + sizeof(struct ipv6hdr) + opts_len);
-				icmp_hdr = (struct icmphdr *)(dst + sizeof(struct iphdr));
-
-				real_len += len_delta + sizeof(struct icmphdr);
-
-				/* There is diffirent between ICMPv4/ICMPv6 protocol codes
-				   IPPROTO_ICMP = 1
-				   IPPROTO_ICMPV6 = 58        */
-				ip_hdr->protocol = IPPROTO_ICMP;
-
-				if (include_flag) {
-					/* !!! Warnig !!! We discard ICMP packets with any ICMP as included
-					   in ICMP Error. But ICMP Error messages can include ICMP Query message
-					   */
-					if (icmp6_hdr->icmp6_type != ICMPV6_ECHO_REQUEST)
-					{
-						PDEBUG("ip6_ip4(): included ICMPv6 in ICMPv6 Error message, packet dropped\n");
-						return -1;
-					}
-				}
-
-			/* Translate ICMPv6 to ICMPv4 */
-				switch (icmp6_hdr->icmp6_type)
-				{
-/* ICMP Error messages */
-			/* Destination Unreachable (Type 1) */
-				case ICMPV6_DEST_UNREACH: /* Type 1 */
-					icmp_hdr->type = ICMP_DEST_UNREACH; /* to Type 3 */
-					icmp_hdr->un.echo.id = 0;
-					icmp_hdr->un.echo.sequence = 0;
-					switch (icmp6_hdr->icmp6_code)
-					{
-					case ICMPV6_NOROUTE: /* Code 0 */
-					case ICMPV6_NOT_NEIGHBOUR: /* Code 2 */
-					case ICMPV6_ADDR_UNREACH: /* Code 3  */
-						icmp_hdr->code = ICMP_HOST_UNREACH; /* To Code 1 */
-						break;
-					case ICMPV6_ADM_PROHIBITED: /* Code 1 */
-						icmp_hdr->code = ICMP_HOST_ANO; /* To Code 10 */
-						break;
-					case ICMPV6_PORT_UNREACH: /* Code 4 */
-						icmp_hdr->code = ICMP_PORT_UNREACH; /* To Code 3 */
-
-						break;
-					default:            /* discard any other codes */
-						PDEBUG("ip6_ip4(): Unknown ICMPv6 Type %d Code %d - packet dropped.\n",
-							   ICMPV6_DEST_UNREACH, icmp6_hdr->icmp6_code);
-						return -1;
-					}
-					break;
-			/* Packet Too Big (Type 2) */
-				case ICMPV6_PKT_TOOBIG: /* Type 2 */
-					icmp_hdr->type = ICMP_DEST_UNREACH; /* to Type 3  */
-					icmp_hdr->code = ICMP_FRAG_NEEDED; /*  to Code 4 */
-					/* Change MTU, RFC 2765 (SIIT), 4.2:
-					   The MTU field needs to be adjusted for the difference between
-					   the IPv4 and IPv6 header sizes taking into account whether or
-					   not the packet in error includes a Fragment header.
-					   */
-					/* !!! Don't implement !!! */
-					icmp_hdr->un.frag.mtu = (__u16) icmp6_hdr->icmp6_mtu;
-					break;
-			/* Time Exceeded (Type 3) */
-				case ICMPV6_TIME_EXCEED:
-					icmp_hdr->type = ICMP_TIME_EXCEEDED; /* to Type 11 */
-					icmp_hdr->code = icmp6_hdr->icmp6_code; /* Code unchanged */
-					break;
-			/* Parameter Problem (Type 4) */
-				case ICMPV6_PARAMPROB:
-					switch (icmp6_hdr->icmp6_code) {
-					case ICMPV6_UNK_NEXTHDR: /* Code 1 */
-						icmp_hdr->type = ICMP_DEST_UNREACH; /* to Type 3 */
-						icmp_hdr->code = ICMP_PROT_UNREACH; /* to Code 2 */
-						break;
-					default: /* if Code != 1 */
-						icmp_hdr->type = ICMP_PARAMETERPROB; /* to Type 12 */
-						icmp_hdr->code = 0; /* to Code 0 */
-						/* Update Pointer field
-						   RFC 2765 (SIIT), 4.2:
-						   The Pointer needs to be updated to point to the corresponding
-						   field in the translated include IP header.
-						   */
-						switch (ntohl(icmp6_hdr->icmp6_pointer))
-						{
-						case 0: /* IPv6 Version -> IPv4 Version */
-							icmp_hdr->un.echo.id = 0;
-							break;
-						case 4: /* IPv6 PayloadLength -> IPv4 Total Length */
-							icmp_hdr->un.echo.id = 0x0002; /* 2 */
-							break;
-						case 6: /* IPv6 Next Header-> IPv4 Protocol */
-							icmp_hdr->un.echo.id = 0x0009; /* 9 */
-							break;
-						case 7: /* IPv6 Hop Limit -> IPv4 TTL */
-							icmp_hdr->un.echo.id = 0x0008; /* 8 */
-							break;
-						case 8: /* IPv6 Src addr -> IPv4 Src addr */
-							icmp_hdr->un.echo.id = 0x000c; /* 12 */
-							break;
-						case 24: /* IPv6 Dst addr -> IPv4 Dst addr*/
-							icmp_hdr->un.echo.id = 0x0010; /* 16 */
-							break;
-						default: /* set all ones in other cases */
-							icmp_hdr->un.echo.id = 0xff;
-							break;
-						}
-						break;
-					}
-					break;
-
-/* End of ICMP Error messages */
-
-			/* Echo Request and Echo Reply (Type 128 and 129)  */
-				case ICMPV6_ECHO_REQUEST:
-					icmperr = 0;        /* not error ICMP message */
-					icmp_hdr->type = ICMP_ECHO; /* to Type 8 */
-					icmp_hdr->code = 0; /* to Code 0 */
-					icmp_hdr->un.echo.id = icmp6_hdr->icmp6_identifier;
-					icmp_hdr->un.echo.sequence = icmp6_hdr->icmp6_sequence;
-					/* copy rest of ICMP data to result packet */
-					if (len_delta > 0)
-						memcpy(((char *)icmp_hdr) + sizeof(struct icmphdr),
-							   ((char *)icmp6_hdr) + sizeof(struct icmp6hdr), len_delta);
-					break;
-				case ICMPV6_ECHO_REPLY:
-					icmperr = 0;        /* not error ICMP message */
-					icmp_hdr->type = ICMP_ECHOREPLY; /* to Type 0 */
-					icmp_hdr->code = 0; /* to Code 0 */
-					icmp_hdr->un.echo.id = icmp6_hdr->icmp6_identifier;
-					icmp_hdr->un.echo.sequence = icmp6_hdr->icmp6_sequence;
-					/* copy rest of ICMP data */
-					if (len_delta > 0)
-						memcpy(((char *)icmp_hdr) + sizeof(struct icmphdr),
-							   ((char *)icmp6_hdr) + sizeof(struct icmp6hdr), len_delta);
-					break;
-				default:
-					/* Unknown error messages. Silently drop. */
-					PDEBUG("ip6_ip4(): unknown ICMPv6 Type %d, packet dropped.\n", icmp6_hdr->icmp6_type);
-					return -1;
-				}
-
-				if (icmperr)
-				{
-					/* If ICMP Error message, we translate IP included packet*/
-					if (len_delta >= sizeof(struct ipv6hdr))
-					{
-						if((inc_opts_len = ip6_ip4((char *)icmp6_hdr + sizeof(struct icmp6hdr), len_delta,
-										           (char *)icmp_hdr + sizeof(struct icmphdr), 1)) == -1) {
-							PDEBUG("ip6_ip4(): incorrect translation of ICMPv6 Error message, packet dropped\n");
-							return -1;
-						}
-						/* correct IPv4 Total Len that = old Total Len
-						   - Options Headers Len in included IP packet
-						   - diffirence between IPv6 Header Len and IPv4 Header Len
-						   */
-						if (ntot_len != 0)
-							ip_hdr->tot_len = htons(ntot_len - inc_opts_len - IP4_IP6_HDR_DIFF);
-						real_len = real_len - inc_opts_len - IP4_IP6_HDR_DIFF;
-					}
-					else if (len_delta > 0)
-					{
-						/* May be it need set 0x0 to rest area in result IPv4 packet,
-						 * but we copy rest data unchanged
-						 */
-						memcpy(((char *)icmp_hdr) + sizeof(struct icmphdr),
-							   ((char *)icmp6_hdr) + sizeof(struct icmp6hdr), len_delta);
-					}
-				}
-
-				/* Calculate IPv4 Header checksum */
-				ip_hdr->check = 0;
-				ip_hdr->check = ip_fast_csum((unsigned char *)ip_hdr, ip_hdr->ihl);
-
-				/* Calculate ICMPv4 checksum */
-				if (ntot_len != 0)
-				{
-					icmp_hdr->checksum = 0;
-					icmp_hdr->checksum = ip_compute_csum((unsigned char *)icmp_hdr, ntohs(ip_hdr->tot_len)
-										             - sizeof(struct iphdr));
-				}
-			}
-			else
-			{
-				PDEBUG("ip6_ip4(): error length ICMP packet, packet dropped.\n");
-				return -1;
-			}
-
-		}
-		/* PROCESS TCP and UDP (and rest data) */
-
-		else {
-			real_len += len_delta;
-			/* we copy rest data to IPv4 packet without changing */
-			memcpy(dst+sizeof(struct iphdr), src + sizeof(struct ipv6hdr) + opts_len, len_delta);
-		}
-	}
-
-	if (include_flag)           /* if it's included IP packet */
-		return opts_len;        /* return options headers length */
-	else
-		return real_len; /* result packet len */
-}
-
-/*
- * ip4_fragment(skb, len, hdr_len, dev, eth_h)
- * to fragment original IPv4 packet if result IPv6 packet will be > 1280
- */
-
-static int ip4_fragment(struct sk_buff *skb, int len, int hdr_len, struct net_device *dev, struct ethhdr *eth_h)
-{
-	struct sk_buff *skb2 = NULL;       /* pointer to new struct sk_buff for transleded packet */
-	char buff[FRAG_BUFF_SIZE+hdr_len]; /* buffer to form new fragment packet */
-	char *cur_ptr = skb->data+hdr_len; /* pointter to current packet data with len = frag_len */
-	struct iphdr *ih4 = (struct iphdr *) skb->data;
-	struct iphdr *new_ih4 = (struct iphdr *) buff; /* point to new IPv4 hdr */
-	struct ethhdr *new_eth_h;   /* point to ether hdr, need to set hard header data in fragment */
-	int data_len = len - hdr_len; /* origin packet data len */
-	int rest_len = data_len;    /* rest data to fragment */
-	int frag_len = 0;           /* current fragment len */
-	int last_frag = 0;          /* last fragment flag, if = 1, it's last fragment */
-	int flag_last_mf = 0;
-	__u16 new_id = 0;           /* to generate identification field */
-	__u16 frag_offset = 0;      /* fragment offset */
-	unsigned int csum;
-	unsigned short udp_len;
-
-#ifdef SIIT_DEBUG
-	printk("siit: it's DF == 0 and result IPv6 packet will be > 1280\n");
-	siit_print_dump(skb->data, hdr_len, "siit: (orig) ipv4_hdr dump");
-#endif
-
-	if ((ntohs(ih4->frag_off) & IP_MF) == 0 )
-		/* it's a case we'll clear MF flag in our last packet */
-		flag_last_mf = 1;
-
-	if (ih4->protocol == IPPROTO_UDP) {
-		if ( (ntohs(ih4->frag_off) & IP_OFFSET) == 0) {
-			struct udphdr *udp_hdr = (struct udphdr *)((char *)ih4 + hdr_len);
-			if (!flag_last_mf) {
-				if (udp_hdr->check == 0) {
-					/* it's a first fragment with ZERO checksum and we drop packet */
-					printk("siit: First fragment of UDP with zero checksum - packet droped\n");
-					printk("siit: addr: %x src port: %d dst port: %d\n",
-						   htonl(ih4->saddr), htons(udp_hdr->source), htons(udp_hdr->dest));
-					return -1;
-				}
-			}
-			else if (udp_hdr->check == 0) {
-				/* Calculate UDP checksum only if it's not fragment */
-				udp_len = ntohs(udp_hdr->len);
-				csum = 0;
-				csum = csum_partial((unsigned char *)udp_hdr, udp_len, csum);
-				udp_hdr->check = csum_tcpudp_magic(ih4->saddr, ih4->daddr, udp_len, IPPROTO_UDP, csum);
-			}
-		}
-	}
-
-	frag_offset = ntohs(ih4->frag_off) & IP_OFFSET;
-
-	new_id = ih4->id;
-
-	while(1) {
-		if (rest_len <= FRAG_BUFF_SIZE) {
-			/* it's last fragmen */
-			frag_len = rest_len; /* rest data */
-			last_frag = 1;
-		}
-		else
-			frag_len = FRAG_BUFF_SIZE;
-
-		/* copy IP header to buffer */
-		memcpy(buff, skb->data, hdr_len);
-		/* copy data to buffer with len = frag_len */
-		memcpy(buff + hdr_len, cur_ptr, frag_len);
-
-		/* set id field in new IPv4 header*/
-		new_ih4->id = new_id;
-
-		/* is it last fragmet */
-		if(last_frag && flag_last_mf)
-			/* clear MF flag */
-			new_ih4->frag_off = htons(frag_offset & (~IP_MF));
-		else
-			/* set MF flag */
-			new_ih4->frag_off = htons(frag_offset | IP_MF);
-
-		/* change packet total length */
-		new_ih4->tot_len = htons(frag_len+hdr_len);
-
-		/* rebuild the header checksum (IP needs it) */
-		new_ih4->check = 0;
-		new_ih4->check = ip_fast_csum((unsigned char *)new_ih4,new_ih4->ihl);
-
-		/* Allocate new sk_buff to compose translated packet */
-		skb2 = dev_alloc_skb(frag_len+hdr_len+dev->hard_header_len+IP4_IP6_HDR_DIFF+IP6_FRAGMENT_SIZE);
-		if (!skb2) {
-			printk(KERN_DEBUG "%s: alloc_skb failure - packet dropped.\n", dev->name);
-			dev_kfree_skb(skb2);
-			return -1;
-		}
-		/* allocate skb->data portion for IP header len, fragment data len and ether header len
-		 * and copy to head ether header from origin skb
-		 */
-		memcpy(skb_put(skb2, frag_len+hdr_len+dev->hard_header_len+IP4_IP6_HDR_DIFF+IP6_FRAGMENT_SIZE), (char *) eth_h,
-			   dev->hard_header_len);
-		/* correct ether header data, ether protocol field to ETH_P_IPV6 */
-		new_eth_h = (struct ethhdr *)skb2->data;
-		new_eth_h->h_proto = htons(ETH_P_IPV6);
-
-		/* reset the mac header */
-		skb_reset_mac_header(skb2);
-
-		/* pull ether header from new skb->data */
-		skb_pull(skb2, dev->hard_header_len);
-		/* set skb protocol to IPV6 */
-		skb2->protocol = htons(ETH_P_IPV6);
-
-		/* call translation function */
-		if ( ip4_ip6(buff, frag_len+hdr_len, skb2->data, 0) == -1) {
-			dev_kfree_skb(skb2);
-			return -1;
-		}
-
-		/*
-		 * Set needed fields in new sk_buff
-		 */
-		skb2->dev = dev;
-		skb2->ip_summed = CHECKSUM_UNNECESSARY;
-		skb2->pkt_type = PACKET_HOST;
-
-		/* Add transmit statistic */
-		siit_stats(dev)->tx_packets++;
-		siit_stats(dev)->tx_bytes += skb2->len;
-
-		/* send packet to upper layer */
-		netif_rx(skb2);
-
-		/* exit if it was last fragment */
-		if (last_frag)
-			break;
-
-		/* correct current data pointer */
-		cur_ptr += frag_len;
-		/* rest data len */
-		rest_len -= frag_len;
-		/* current fragment offset */
-		frag_offset = (frag_offset*8 + frag_len)/8;
-	}
-
-	return 0;
-}
-/*
- * Transmit a packet (called by the kernel)
- *
- * siit_xmit(skb, dev)
- *
- * where
- * skb - pointer to struct sk_buff with incomed packet
- * dev - pointer to struct device on which packet revieved
- *
- * Statistic:
- * for all incoming packes:
- *            stats.rx_bytes+=skb->len
- *            stats.rx_packets++
- * for packets we can't transle:
- *            stats.tx_errors++
- * device busy:
- *            stats.tx_errors++
- * for packets we can't allocate sk_buff:
- *            stats.tx_dropped++
- * for outgoing packes:
- *            stats.tx_packets++
- *            stats.tx_bytes+=skb2->len !!! But we don't set skb2->len !!!
- */
-
-static int siit_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct sk_buff *skb2 = NULL;/* pointer to new struct sk_buff for transleded packet */
-	struct ethhdr *eth_h;       /* pointer to incoming Ether header */
-	int len;                    /* original packets length */
-	int new_packet_len;
-	int skb_delta = 0;          /* delta size for allocate new skb */
-	char new_packet_buff[2048];
-
-	/* Check pointer to sk_buff and device structs */
-	if (skb == NULL || dev == NULL)
-		return -EINVAL;
-
-	/* Add receive statistic */
-	siit_stats(dev)->rx_bytes += skb->len;
-	siit_stats(dev)->rx_packets++;
-
-	dev->trans_start = jiffies;
-
-	/* Upper layer (IP) protocol forms sk_buff for outgoing packet
-	 * and sets IP header + Ether header too. IP layer sets outgoing
-	 * device in sk_buff->dev.
-	 * In function (from linux/net/core/dev.c) ther is a call to
-	 * device transmit function (dev->hard_start_xmit):
-	 *
-	 *    dev_queue_xmit(struct sk_buff *skb)
-	 *    {
-	 *    ...
-	 *          device *dev = skb->dev;
-	 *    ...
-	 *          dev->hard_start_xmit(skb, dev);
-	 *    ...
-	 *    }
-	 * We save pointer to ether header in eth_h and skb_pull ether header
-	 * from data field of skb_buff
-	 */
-
-	eth_h = (struct ethhdr *)skb->data; /* point to incoming packet Ether Header */
-
-#ifdef SIIT_DEBUG
-	siit_print_dump(skb->data, ETH_HLEN, "siit: eth_hdr dump");
-#endif
-
-	/* Remove hardware header from origin sk_buff */
-	skb_pull(skb,dev->hard_header_len);
-
-	/*
-	 * Process IPv4 paket
-	 */
-	if (ntohs(skb->protocol) == ETH_P_IP) {
-		int hdr_len;            /* IPv4 header length */
-		int data_len;           /* IPv4 data length */
-		struct iphdr *ih4;      /* pointer to IPv4 header */
-		struct icmphdr *icmp_hdr;   /* point to current ICMPv4 header struct */
-
-		ih4 = (struct iphdr *)skb->data; /* point to incoming packet's IPv4 header */
-
-		/* Check IPv4 Total Length */
-		if (skb->len != ntohs(ih4->tot_len)) {
-			PDEBUG("siit_xmit(): Different skb_len %x and ip4 tot_len %x - packet dropped.\n",
-				   skb->len, ih4->tot_len);
-			siit_stats(dev)->tx_errors++;
-			dev_kfree_skb(skb);
-			return 0;
-		}
-
-		len = skb->len;     /* packet's total len */
-		hdr_len = (int)(ih4->ihl * 4); /* packet's header len */
-		data_len = len - hdr_len; /* packet's data len */
-
-		/* If DF == 0 */
-		if ( (ntohs(ih4->frag_off) & IP_DF) == 0 ) {
-			/* If result IPv6 packet will be > 1280
-			   we need to fragment original IPv4 packet
-			*/
-			if ( data_len > FRAG_BUFF_SIZE ) {
-				/* call function that fragment packet and translate to IPv6 each fragment
-				 * and send to upper layer
-				 */
-				if ( ip4_fragment(skb, len, hdr_len, dev, eth_h) == -1) {
-					siit_stats(dev)->tx_errors++;
-				}
-				/* Free incoming skb */
-				dev_kfree_skb(skb);
-				/* Device can accept a new packet */
-
-				return 0;
-
-			}
-		}
-		/* If DF == 1 && MF == 0 && Fragment Offset == 0
-		 * we don't include fragment header
-		 */
-		if ( ntohs(ih4->frag_off) == IP_DF )
-			skb_delta = IP4_IP6_HDR_DIFF; /* delta is +20 */
-		else
-			skb_delta = IP4_IP6_HDR_DIFF + IP6_FRAGMENT_SIZE; /* delta is +20 and +8 */
-
-		/* If it's ICMP, check is it included IP packet in it */
-		if ( ih4->protocol == IPPROTO_ICMP) {
-			icmp_hdr = (struct icmphdr *) (skb->data+hdr_len); /* point to ICMPv4 header */
-			if ( icmp_hdr->type != ICMP_ECHO && icmp_hdr->type != ICMP_ECHOREPLY) {
-				/*
-				 * It's ICMP Error that has included IP packet
-				 * we'll add only +20 because we don't include Fragment Header
-				 * into translated included IP packet
-				 */
-				skb_delta += IP4_IP6_HDR_DIFF;
-			}
-		}
-
-		/* Allocate new sk_buff to compose translated packet */
-		skb2 = dev_alloc_skb(len+dev->hard_header_len+skb_delta);
-		if (!skb2) {
-			printk(KERN_DEBUG "%s: alloc_skb failure - packet dropped.\n", dev->name);
-			dev_kfree_skb(skb);
-			siit_stats(dev)->rx_dropped++;
-
-			return 0;
-		}
-		/* allocate skb->data portion = IPv4 packet len + ether header len
-		 * + skb_delta (max = two times (diffirence between IPv4 header and
-		 * IPv6 header + Frag Header), second for included packet,
-		 * and copy to head of skb->data ether header from origin skb
-		 */
-		memcpy(skb_put(skb2, len+dev->hard_header_len+skb_delta), (char *)eth_h, dev->hard_header_len);
-		/* correct ether header data, ether protocol field to ETH_P_IPV6 */
-		eth_h = (struct ethhdr *)skb2->data;
-		eth_h->h_proto = htons(ETH_P_IPV6);
-		skb_reset_mac_header(skb2);
-		/* remove ether header from new skb->data,
-		 * NOTE! data will rest, pointer to data and data len will change
-		 */
-		skb_pull(skb2,dev->hard_header_len);
-		/* set skb protocol to IPV6 */
-		skb2->protocol = htons(ETH_P_IPV6);
-
-		/* call translation function */
-		if (ip4_ip6(skb->data, len, skb2->data, 0) == -1 ) {
-			dev_kfree_skb(skb);
-			dev_kfree_skb(skb2);
-			siit_stats(dev)->rx_errors++;
-
-			return 0;
-		}
-	}
-	/*
-	 * IPv6 paket
-	 */
-	else if (ntohs(skb->protocol) == ETH_P_IPV6) {
-
-#ifdef SIIT_DEBUG
-		siit_print_dump(skb->data, sizeof(struct ipv6hdr), "siit: (in) ip6_hdr dump");
-#endif
-		/* packet len = skb->data len*/
-		len = skb->len;
-
-		/* call translation function */
-		if ((new_packet_len = ip6_ip4(skb->data, len, new_packet_buff, 0)) == -1 )
-		{
-			PDEBUG("siit_xmit(): error translation ipv6->ipv4, packet dropped.\n");
-			siit_stats(dev)->rx_dropped++;
-			goto end;
-		}
-
-		/* Allocate new sk_buff to compose translated packet */
-		skb2 = dev_alloc_skb(new_packet_len + dev->hard_header_len);
-		if (!skb2) {
-			printk(KERN_DEBUG "%s: alloc_skb failure, packet dropped.\n", dev->name);
-			siit_stats(dev)->rx_dropped++;
-			goto end;
-		}
-		memcpy(skb_put(skb2, new_packet_len + dev->hard_header_len), (char *)eth_h, dev->hard_header_len);
-		eth_h = (struct ethhdr *)skb2->data;
-		eth_h->h_proto = htons(ETH_P_IP);
-		skb_reset_mac_header(skb2);
-		skb_pull(skb2, dev->hard_header_len);
-		memcpy(skb2->data, new_packet_buff, new_packet_len);
-		skb2->protocol = htons(ETH_P_IP);
-	}
-	else {
-		PDEBUG("siit_xmit(): unsupported protocol family %x, packet dropped.\n", skb->protocol);
-		goto end;
-	}
-
-	/*
-	 * Set needed fields in new sk_buff
-	 */
-	skb2->pkt_type = PACKET_HOST;
-	skb2->dev = dev;
-	skb2->ip_summed = CHECKSUM_UNNECESSARY;
-
-	/* Add transmit statistic */
-	siit_stats(dev)->tx_packets++;
-	siit_stats(dev)->tx_bytes += skb2->len;
-
-	/* Send packet to upper layer protocol */
-	netif_rx(skb2);
-
-end:
-	dev_kfree_skb(skb);
-
-	return 0;
-}
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
-static bool header_ops_init = false;
-static struct header_ops siit_header_ops ____cacheline_aligned;
-#endif
-
-#if !(defined CONFIG_COMPAT_NET_DEV_OPS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
-static const struct net_device_ops siit_netdev_ops = {
-	.ndo_open		= siit_open,
-	.ndo_stop		= siit_release,
-	.ndo_start_xmit		= siit_xmit,
-};
-#endif
-
-/*
- * The init function initialize of the SIIT device..
- * It is invoked by register_netdev()
- */
-
-static void
-siit_init(struct net_device *dev)
-{
-	ether_setup(dev);    /* assign some of the fields */
-	random_ether_addr(dev->dev_addr);
-
-	/*
-	 * Assign device function.
-	 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
-	dev->open            = siit_open;
-	dev->stop            = siit_release;
-	dev->hard_start_xmit = siit_xmit;
-#else
-#if !(defined CONFIG_COMPAT_NET_DEV_OPS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
-	dev->netdev_ops = &siit_netdev_ops;
-#endif
-#endif
-	dev->flags           |= IFF_NOARP;     /* ARP not used */
-	dev->tx_queue_len = 10;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-	dev->hard_header_cache = NULL;        /* Disable caching */
-	memset(netdev_priv(dev), 0, sizeof(struct net_device_stats));
-	dev->get_stats = siit_get_stats;
-#else
-	if (!header_ops_init) {
-		memcpy(&siit_header_ops, dev->header_ops, sizeof(struct header_ops));
-		siit_header_ops.cache = NULL;
-	}
-	dev->header_ops = &siit_header_ops;
-#endif
-}
-
-/*
- * Finally, the module stuff
- */
-static struct net_device *siit_dev = NULL;
-
-int init_module(void)
-{
-	int res = -ENOMEM;
-	int priv_size;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-	priv_size = sizeof(struct net_device_stats);
-#else
-	priv_size = sizeof(struct header_ops);
-#endif
-	siit_dev = alloc_netdev(priv_size, "siit%d", siit_init);
-	if (!siit_dev)
-		goto err_alloc;
-
-	res = register_netdev(siit_dev);
-	if (res)
-		goto err_register;
-
-	return 0;
-
-err_register:
-	free_netdev(siit_dev);
-err_alloc:
-	printk(KERN_ERR "Error creating siit device: %d\n", res);
-	return res;
-}
-
-void cleanup_module(void)
-{
-	unregister_netdev(siit_dev);
-	free_netdev(siit_dev);
-}
-
-
diff --git a/package/siit/src/siit.h b/package/siit/src/siit.h
deleted file mode 100644
index 47cf77645f..0000000000
--- a/package/siit/src/siit.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * siit.h -- definitions for the SIIT module
- *
- *
- */
-
-/*
- * Constants
- */
-
-/* SIIT_ETH control the name of SIIT interface:
- * 0 - interface name is siit0,
- * 1 - interface name is ethX.
- */
-#define SIIT_ETH 0
-
-#define BUFF_SIZE 4096
-#define FRAG_BUFF_SIZE 1232     /* IPv6 max fragment size without IPv6 header 
-                                 * to fragmanet IPv4 if result IPv6 packet will be > 1280
-                                 */
-
-#define TRANSLATED_PREFIX 0x0000ffff /* third byte in IPv4-translated addr prefix */
-#define MAPPED_PREFIX 0x0000ffff     /* third byte in IPv4-mapped addr prefix */
-
-#define IP4_IP6_HDR_DIFF 20     /* diffirence between IPv4 and IPv6 headers */
-#define IP6_FRAGMENT_SIZE 8     /* size of Fragment Header */
-
-/* IPv6 header fields masks */
-#define IP6F_OFF_MASK       0xfff8  /* mask out offset from frag_off */
-#define IP6F_RESERVED_MASK  0x0006  /* reserved bits in frag_off */
-#define IP6F_MORE_FRAG      0x0001  /* more-fragments flag */
-
-
-
-/*
- * Macros to help debugging
- */
-
-#undef PDEBUG             /* undef it, just in case */
-#ifdef SIIT_DEBUG
-#  ifdef __KERNEL__
-     /* This one if debugging is on, and kernel space */
-#    define PDEBUG(fmt, args...) printk(KERN_DEBUG "siit: " fmt, ## args)
-#  else
-     /* This one for user space */
-#    define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
-#  endif
-#else
-#  define PDEBUG(fmt, args...) /* not debugging: nothing */
-#endif
-
-#undef PDEBUGG
-#define PDEBUGG(fmt, args...)
-
-
-
-
-
-
-
-
diff --git a/package/wprobe/Makefile b/package/wprobe/Makefile
deleted file mode 100644
index de1ba6d636..0000000000
--- a/package/wprobe/Makefile
+++ /dev/null
@@ -1,143 +0,0 @@
-#
-# Copyright (C) 2008-2010 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=wprobe
-PKG_VERSION:=1
-PKG_RELEASE:=1
-
-PKG_BUILD_DEPENDS:=PACKAGE_wprobe-export:libipfix
-
-PKG_CONFIG_DEPENDS = \
-	CONFIG_PACKAGE_kmod-wprobe \
-	CONFIG_PACKAGE_wprobe-export \
-
-include $(INCLUDE_DIR)/package.mk
-
-# XXX: build failure on cris
-# wprobe-lib.c:145: error: 'packed' attribute ignored for field of type 'struct <anonymous>'
-# wprobe-lib.c:149: error: 'packed' attribute ignored for field of type 'struct <anonymous>'
-
-define Package/wprobe/Default
-  DEPENDS:=@(!(TARGET_ps3||TARGET_pxcab||cris)||BROKEN)
-endef
-
-define KernelPackage/wprobe
-$(call Package/wprobe/Default)
-  SUBMENU:=Network Support
-  TITLE:=Wireless driver probe infrastructure
-  MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
-  FILES:= \
-  	$(PKG_BUILD_DIR)/kernel/wprobe.ko
-  AUTOLOAD:=$(call AutoLoad,01,wprobe)
-endef
-
-define KernelPackage/wprobe/description
-  A module that exports measurement data from wireless driver to user space
-endef
-
-define Package/wprobe-util
-$(call Package/wprobe/Default)
-  SECTION:=net
-  CATEGORY:=Network
-  DEPENDS+=+kmod-wprobe +libnl-tiny
-  TITLE:=Wireless measurement utility
-endef
-
-define Package/wprobe-util/description
-  wprobe-util uses the wprobe kernel module to query
-  wireless driver measurement data from an interface
-endef
-
-define Package/wprobe-export
-$(call Package/wprobe/Default)
-  SECTION:=net
-  CATEGORY:=Network
-  DEPENDS+=+wprobe-util
-  TITLE:=Wireless measurement data exporter
-endef
-
-define Package/wprobe-export/description
-  wprobe-export uses the wprobe kernel module to export
-  wireless driver measurement data via the IPFIX protocol
-endef
-
-define Package/wprobe-export/conffiles
-/etc/config/wprobe
-endef
-
-define Build/Prepare
-	mkdir -p $(PKG_BUILD_DIR)
-	$(CP) src/* $(PKG_BUILD_DIR)/
-endef
-
-TARGET_CPPFLAGS := \
-	-D_GNU_SOURCE \
-	-I$(STAGING_DIR)/usr/include/libnl-tiny \
-	$(TARGET_CPPFLAGS)
-
-ifdef CONFIG_PACKAGE_kmod-wprobe
-  define Build/Compile/kmod
-	$(MAKE) -C $(LINUX_DIR) \
-		CROSS_COMPILE="$(KERNEL_CROSS)" \
-		ARCH="$(LINUX_KARCH)" \
-		SUBDIRS="$(PKG_BUILD_DIR)/kernel" \
-		KERNELDIR=$(LINUX_DIR) \
-		CC="$(TARGET_CC)" \
-		EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/kernel" \
-		modules
-  endef
-endif
-
-define Build/Compile/lib
-	$(MAKE) -C $(PKG_BUILD_DIR)/user \
-		$(TARGET_CONFIGURE_OPTS) \
-		CFLAGS="$(TARGET_CFLAGS)" \
-		CPPFLAGS="$(TARGET_CPPFLAGS) -I$(PKG_BUILD_DIR)/kernel" \
-		LDFLAGS="$(TARGET_LDFLAGS)" \
-		HOST_OS=Linux \
-		LIBNL="-lnl-tiny"
-endef
-
-ifdef CONFIG_PACKAGE_wprobe-export
-  define Build/Compile/exporter
-	$(MAKE) -C $(PKG_BUILD_DIR)/exporter \
-		$(TARGET_CONFIGURE_OPTS) \
-		CFLAGS="$(TARGET_CFLAGS)" \
-		CPPFLAGS="$(TARGET_CPPFLAGS) -I$(PKG_BUILD_DIR)/kernel -I$(PKG_BUILD_DIR)/user" \
-		LDFLAGS="$(TARGET_LDFLAGS)" \
-		LIBS="$(PKG_BUILD_DIR)/user/libwprobe.a $(STAGING_DIR)/usr/lib/libipfix.a $(STAGING_DIR)/usr/lib/libipfixmisc.a -lnl-tiny -lm"
-  endef
-endif
-
-define Build/Compile
-	$(Build/Compile/kmod)
-	$(Build/Compile/lib)
-	$(Build/Compile/exporter)
-endef
-
-define Build/InstallDev
-	$(INSTALL_DIR) $(1)/usr/include/wprobe
-	$(CP) $(PKG_BUILD_DIR)/kernel/linux $(1)/usr/include/wprobe
-endef
-
-define Package/wprobe-util/install
-	$(INSTALL_DIR) $(1)/sbin
-	$(INSTALL_BIN) $(PKG_BUILD_DIR)/user/wprobe-util $(1)/sbin/
-endef
-
-define Package/wprobe-export/install
-	$(INSTALL_DIR) $(1)/sbin $(1)/etc/init.d $(1)/etc/config
-	$(INSTALL_BIN) ./files/wprobe.init $(1)/etc/init.d/wprobe
-	$(INSTALL_BIN) ./files/wprobe.config $(1)/etc/config/wprobe
-	$(INSTALL_BIN) $(PKG_BUILD_DIR)/exporter/wprobe-export $(1)/sbin/
-endef
-
-$(eval $(call KernelPackage,wprobe))
-$(eval $(call BuildPackage,wprobe-util))
-$(eval $(call BuildPackage,wprobe-export))
diff --git a/package/wprobe/files/wprobe.config b/package/wprobe/files/wprobe.config
deleted file mode 100644
index 63518ef6e4..0000000000
--- a/package/wprobe/files/wprobe.config
+++ /dev/null
@@ -1,10 +0,0 @@
-config export
-	# uncomment this line to enable ipfix export:
-	# option type ipfix
-	option ifname ath0
-	option host ipfix-col
-	option proto tcp
-
-# enable public wprobe protocol access
-config export
-	option type wprobe
diff --git a/package/wprobe/files/wprobe.init b/package/wprobe/files/wprobe.init
deleted file mode 100755
index b35246d42e..0000000000
--- a/package/wprobe/files/wprobe.init
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/bin/sh /etc/rc.common
-START=90
-EXPORTER=/sbin/wprobe-export
-UTIL=/sbin/wprobe-util
-
-wprobe_ssd() {
-	local cmd="$1"; shift
-	local type="$1"; shift
-	local app="$1"; shift
-	start-stop-daemon "$cmd" -p "/var/run/wprobe-$type.pid" -b ${app:+-x "$app"} -m -- "$@"
-}
-
-stop_wprobe() {
-	local type="$1"
-	[ -f "/var/run/wprobe-$type.pid" ] && wprobe_ssd -K "$type"
-	rm -f "/var/run/wprobe-$type.pid"
-}
-
-config_wprobe() {
-	config_get ifname "$cfg" ifname
-	config_get interval "$cfg" interval
-	[ -n "$interval" ] || interval=100
-	$UTIL "$ifname" -i "$interval" 2>/dev/null >/dev/null
-}
-
-start_proxy() {
-	config_get port "$cfg" port
-	wprobe_ssd -S proxy "$UTIL" -P -p "${port:-17990}"
-}
-
-start_ipfix() {
-	local cfg="$1"
-	config_get ifname "$cfg" ifname
-	config_get host "$cfg" host
-	config_get port "$cfg" port
-	config_get proto "$cfg" proto
-	case "$proto" in
-		sctp) proto="-s";;
-		tcp) proto="-t";;
-		udp) proto="-u";;
-		*) proto="-t";;
-	esac
-	[ -z "$ifname" -o -z "$host" ] && {
-		echo "wprobe-export: missing host or interface name in config $cfg"
-		return
-	}
-	config_wprobe "$cfg"
-	wprobe_ssd -S "export-$cfg" "$EXPORTER" "$proto" -i "$ifname" -c "$host" -p "${port:-4739}"
-}
-
-start_export() {
-	local cfg="$1"
-	config_get export_type "$cfg" type
-	case "$export_type" in 
-		ipfix) [ -x "$EXPORTER" ] && start_ipfix "$cfg";;
-		wprobe) start_proxy "$cfg";;
-	esac
-}
-
-stop() {
-	for f in /var/run/wprobe-*.pid; do
-		CFG="${f%%.pid}"
-		CFG="${CFG##/var/run/wprobe-}"
-		stop_wprobe "$CFG"
-	done
-}
-
-start() {
-	config_load wprobe
-	config_foreach config_wprobe interface
-	config_foreach start_export export
-}
diff --git a/package/wprobe/src/Makefile.inc b/package/wprobe/src/Makefile.inc
deleted file mode 100644
index 5044c0a55a..0000000000
--- a/package/wprobe/src/Makefile.inc
+++ /dev/null
@@ -1,12 +0,0 @@
-HOST_OS=$(shell uname)
-
-CC=gcc
-AR=ar
-RANLIB=ranlib
-
-WFLAGS = -Wall -Werror -Wno-format
-CFLAGS?=-O2
-CPPFLAGS=
-LDFLAGS=
-LIBS=
-
diff --git a/package/wprobe/src/exporter/Makefile b/package/wprobe/src/exporter/Makefile
deleted file mode 100644
index 9f8150729c..0000000000
--- a/package/wprobe/src/exporter/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-include ../Makefile.inc
-CPPFLAGS += -I../kernel -I../user
-
-wprobe-export: wprobe-export.c
-	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
diff --git a/package/wprobe/src/exporter/wprobe-export.c b/package/wprobe/src/exporter/wprobe-export.c
deleted file mode 100644
index a0e52e2f4e..0000000000
--- a/package/wprobe/src/exporter/wprobe-export.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
-**     exporter.c - example exporter
-**
-**     Copyright Fraunhofer FOKUS
-**
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include <ipfix_def.h>
-#include <ipfix_def_fokus.h>
-#include <ipfix_fields_fokus.h>
-
-#include <ipfix.h>
-#include <mlog.h>
-#include <wprobe.h>
-#include <stdbool.h>
-
-static ipfix_datarecord_t g_data  = { NULL, NULL, 0 };
-static int do_close = 0;
-
-struct wprobe_mapping {
-	int id;
-	bool counter;
-	const char *wprobe_id;
-	struct wprobe_value *val;
-};
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(_array) (sizeof(_array) / sizeof((_array)[0]))
-#endif
-
-#define WMAP(_id, _name, ...) \
-	{ \
-		.counter = false, \
-		.id = IPFIX_FT_WPROBE_##_id##_N, \
-		.wprobe_id = _name \
-		, ## __VA_ARGS__ \
-	}
-
-#define WMAP_COUNTER(_id, _name, ...) \
-	{ \
-		.counter = true, \
-		.id = IPFIX_FT_WPROBE_##_id, \
-		.wprobe_id = _name \
-		, ## __VA_ARGS__ \
-	}
-
-
-#define WPROBE_OFFSET	2
-
-static struct wprobe_mapping map_globals[] = {
-	WMAP(NOISE, "noise"),
-	WMAP(PHY_BUSY, "phy_busy"),
-	WMAP(PHY_RX, "phy_rx"),
-	WMAP(PHY_TX, "phy_tx"),
-	WMAP_COUNTER(FRAMES, "frames"),
-	WMAP_COUNTER(PROBEREQ, "probereq"),
-};
-
-static struct wprobe_mapping map_perlink[] = {
-	WMAP(IEEE_TX_RATE, "tx_rate"),
-	WMAP(IEEE_RX_RATE, "rx_rate"),
-	WMAP(RSSI, "rssi"),
-	WMAP(SIGNAL, "signal"),
-	WMAP(RETRANSMIT_200, "retransmit_200"),
-	WMAP(RETRANSMIT_400, "retransmit_400"),
-	WMAP(RETRANSMIT_800, "retransmit_800"),
-	WMAP(RETRANSMIT_1600, "retransmit_1600"),
-};
-
-static unsigned char link_local[6];
-static char link_default[6];
-static int nfields = 0;
-
-#define FOKUS_USERID	12325
-
-static void
-match_template(struct wprobe_mapping *map, int n, struct list_head *list)
-{
-	struct wprobe_attribute *attr;
-	int i, j, last = -1;
-
-	list_for_each_entry(attr, list, list) {
-		for (i = 0; i < n; i++) {
-			j = (last + 1 + i) % n;
-			if (!strcmp(attr->name, map[j].wprobe_id))
-				goto found;
-		}
-		continue;
-found:
-		last = j;
-		map[j].val = &attr->val;
-		memset(&attr->val, 0, sizeof(attr->val));
-		nfields++;
-	}
-}
-
-/* name: export_ipfix_get_template()
- */
-static ipfix_template_t *
-prepare_template(ipfix_t *handle)
-{
-    ipfix_template_t *t = NULL;
-	int size = 3 * nfields + WPROBE_OFFSET;
-    int i;
-
-    if (ipfix_new_data_template( handle, &t, size) < 0) {
-        mlogf( 0, "ipfix_new_template() failed: %s\n", strerror(errno) ); 
-		exit(1);
-    }
-
-	ipfix_add_field(handle, t, 0, IPFIX_FT_SOURCEMACADDRESS, 6);
-	ipfix_add_field(handle, t, 0, IPFIX_FT_DESTINATIONMACADDRESS, 6);
-
-	g_data.lens = calloc(size, sizeof(g_data.lens[0]));
-	g_data.lens[0] = 6;
-	g_data.lens[1] = 6;
-	for (i = WPROBE_OFFSET; i < size; i++)
-		g_data.lens[i] = 4;
-
-	g_data.addrs = calloc(size, sizeof(g_data.addrs[0]));
-	g_data.addrs[0] = link_local;
-	g_data.maxfields = WPROBE_OFFSET;
-	return t;
-}
-
-static void
-add_template_fields(ipfix_t *handle, ipfix_template_t *t, struct wprobe_mapping *map, int n)
-{
-	int f = g_data.maxfields;
-	int i;
-
-    for (i = 0; i < n; i++) {
-		if (!map[i].val)
-			continue;
-
-		if (map[i].counter)
-			g_data.addrs[f++] = &map[i].val->U32;
-		else
-			g_data.addrs[f++] = &map[i].val->n;
-
-        if (ipfix_add_field( handle, t, FOKUS_USERID, map[i].id + 0, 4) < 0)
-            exit(1);
-
-		if (map[i].counter)
-			continue;
-
-		g_data.lens[f] = 8;
-		g_data.addrs[f++] = &map[i].val->s;
-
-		g_data.lens[f] = 8;
-		g_data.addrs[f++] = &map[i].val->ss;
-        if (ipfix_add_field( handle, t, FOKUS_USERID, map[i].id + 1, 8) < 0)
-            exit(1);
-        if (ipfix_add_field( handle, t, FOKUS_USERID, map[i].id + 2, 8) < 0)
-            exit(1);
-    }
-	g_data.maxfields = f;
-}
-
-static void
-wprobe_dump_data(ipfix_t *ipfixh, ipfix_template_t *ipfixt, struct wprobe_iface *dev)
-{
-	struct wprobe_link *link;
-
-	wprobe_update_links(dev);
-	wprobe_request_data(dev, NULL);
-	if (list_empty(&dev->links)) {
-		g_data.addrs[1] = link_default;
-		ipfix_export_array(ipfixh, ipfixt, g_data.maxfields, g_data.addrs, g_data.lens);
-		ipfix_export_flush(ipfixh);
-	}
-	list_for_each_entry(link, &dev->links, list) {
-		g_data.addrs[1] = link->addr;
-		wprobe_request_data(dev, link->addr);
-		ipfix_export_array(ipfixh, ipfixt, g_data.maxfields, g_data.addrs, g_data.lens);
-		ipfix_export_flush(ipfixh);
-	}
-}
-
-int main ( int argc, char **argv )
-{
-	struct wprobe_iface *dev = NULL;
-    ipfix_template_t  *ipfixt = NULL;
-    ipfix_t *ipfixh = NULL;
-    int protocol = IPFIX_PROTO_TCP;
-    char *chost = NULL;
-	char *ifname = NULL;
-    int sourceid = 12345;
-    int port = IPFIX_PORTNO;
-    int verbose_level = 0;
-    int opt, i = 10;
-	char *err = NULL;
-
-	while ((opt = getopt(argc, argv, "hi:c:p:vstu")) != EOF) {
-		switch (opt) {
-		case 'p':
-			if ((port=atoi(optarg)) <0) {
-				fprintf( stderr, "Invalid -p argument!\n" );
-				exit(1);
-			}
-			break;
-		case 'i':
-			ifname = optarg;
-			break;
-		case 'c':
-			chost = optarg;
-			break;
-
-		case 's':
-			protocol = IPFIX_PROTO_SCTP;
-			break;
-
-		case 't':
-			protocol = IPFIX_PROTO_TCP;
-			break;
-
-		case 'u':
-			protocol = IPFIX_PROTO_UDP;
-			break;
-
-		case 'v':
-			verbose_level ++;
-			break;
-
-		case 'h':
-		default:
-			fprintf(stderr, "usage: %s [-hstuv] -i <interface> -c <collector> [-p portno]\n"
-					 "  -h               this help\n"
-					 "  -i <interface>   wprobe interface\n"
-					 "  -c <collector>   collector address\n"
-					 "  -p <portno>      collector port number (default=%d)\n"
-					 "  -s               send data via SCTP\n"
-					 "  -t               send data via TCP (default)\n"
-					 "  -u               send data via UDP\n"
-					 "  -v               increase verbose level\n\n",
-					 argv[0], IPFIX_PORTNO  );
-			exit(1);
-		}
-	}
-
-	if (!ifname) {
-		fprintf(stderr, "No interface specified\n");
-		return -1;
-	}
-
-	if (!chost) {
-		fprintf(stderr, "No collector specified\n");
-		return -1;
-	}
-
-	dev = wprobe_get_auto(ifname, &err);
-	if (!dev || (list_empty(&dev->global_attr) && list_empty(&dev->link_attr))) {
-		fprintf(stderr, "Cannot connect to wprobe on interface '%s': %s\n", ifname, (err ? err : "Unknown error"));
-		return -1;
-	}
-
-	match_template(map_globals, ARRAY_SIZE(map_globals), &dev->global_attr);
-	match_template(map_perlink, ARRAY_SIZE(map_perlink), &dev->link_attr);
-	if (nfields == 0) {
-		fprintf(stderr, "No usable attributes found\n");
-		return -1;
-	}
-
-    mlog_set_vlevel( verbose_level );
-    if (ipfix_init() < 0) {
-        fprintf( stderr, "cannot init ipfix module: %s\n", strerror(errno) );
-        exit(1);
-    }
-
-    ipfix_add_vendor_information_elements(ipfix_ft_fokus);
-    if (ipfix_open(&ipfixh, sourceid, IPFIX_VERSION) < 0) {
-        fprintf( stderr, "ipfix_open() failed: %s\n", strerror(errno) );
-        exit(1);
-    }
-
-    if (ipfix_add_collector( ipfixh, chost, port, protocol ) < 0) {
-        fprintf( stderr, "ipfix_add_collector(%s,%d) failed: %s\n", 
-                 chost, port, strerror(errno));
-        exit(1);
-    }
-
-	fprintf(stderr, "Local link address: %02x:%02x:%02x:%02x:%02x:%02x\n",
-		link_local[0], link_local[1], link_local[2],
-		link_local[3], link_local[4], link_local[5]);
-
-	ipfixt = prepare_template(ipfixh);
-	add_template_fields(ipfixh, ipfixt, map_globals, ARRAY_SIZE(map_globals));
-	add_template_fields(ipfixh, ipfixt, map_perlink, ARRAY_SIZE(map_perlink));
-
-	while (!do_close) {
-		sleep(1);
-		wprobe_dump_data(ipfixh, ipfixt, dev);
-    }
-
-    ipfix_delete_template( ipfixh, ipfixt );
-    ipfix_close( ipfixh );
-    ipfix_cleanup();
-    exit(0);
-}
diff --git a/package/wprobe/src/exporter/wprobe-export.h b/package/wprobe/src/exporter/wprobe-export.h
deleted file mode 100644
index 89da9e86e3..0000000000
--- a/package/wprobe/src/exporter/wprobe-export.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-/**
- * struct wprobe_value: data structure for attribute values
- * see kernel api netlink attributes for more information
- */
-struct wprobe_value {
-	/* attribute value */
-	union data {
-		const char *STRING;
-		uint8_t U8;
-		uint16_t U16;
-		uint32_t U32;
-		uint64_t U64;
-		int8_t S8;
-		int16_t S16;
-		int32_t S32;
-		int64_t S64;
-	} data;
-	/* statistics */
-	int64_t s, ss;
-	double avg, stdev;
-	unsigned int n;
-	void *usedata;  /* Pointer to used data.something */
-};
-
-struct exporter_data {
-	int id; /* ipfix id */
-        int userid; /* focus or global */
-	int size; /* size in byte*/
-	struct wprobe_value val;
-};
diff --git a/package/wprobe/src/filter/README.txt b/package/wprobe/src/filter/README.txt
deleted file mode 100644
index 6fa265e4f8..0000000000
--- a/package/wprobe/src/filter/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-To compile pfc you need at least libpcap version 1.0, as it requires proper radiotap header support
diff --git a/package/wprobe/src/filter/gen_filter.pl b/package/wprobe/src/filter/gen_filter.pl
deleted file mode 100755
index f03f477a49..0000000000
--- a/package/wprobe/src/filter/gen_filter.pl
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/perl
-use strict;
-
-# helpers for custom packet format
-# bytes 0-7 are used by a dummy radiotap header
-my $WLAN_LEN = "radio[8:2]";
-my $SNR = "radio[10:1]";
-my $DEFAULT = undef;
-
-my $MAGIC = "WPFF";
-my $VERSION = 1; # filter binary format version
-my $HDRLEN = 3; # assumed storage space for custom fields
-
-my $output = "filter.bin";
-my $config = {
-	"packetsize" => [
-		[ "small", "$WLAN_LEN < 250" ],
-		[ "medium", "$WLAN_LEN < 800" ],
-		[ "big", $DEFAULT ],
-	],
-	"snr" => [
-		[ "low", "$SNR < 10" ],
-		[ "medium", "$SNR < 20" ],
-		[ "high", $DEFAULT ],
-	],
-	"type" => [
-		[ "beacon", "type mgt subtype beacon" ],
-		[ "data", "type data subtype data" ],
-		[ "qosdata", "type data subtype qos-data" ],
-		[ "other", "$DEFAULT" ]
-	]
-};
-
-sub escape_q($) {
-	my $str = shift;
-	$str =~ s/'/'\\''/g;
-	return $str;
-}
-
-my $GROUPS = scalar(keys %$config);
-open OUTPUT, ">$output" or die "Cannot open output file: $!\n";
-print OUTPUT pack("a4CCn", $MAGIC, $VERSION, $HDRLEN, $GROUPS);
-
-foreach my $groupname (keys %$config) {
-	my $default = 0;
-	my $group = $config->{$groupname};
-	print OUTPUT pack("a32N", $groupname, scalar(@$group));
-	foreach my $filter (@$group) {
-		if (!$filter->[1]) {
-			$default > 0 and print "Cannot add more than one default filter per group: $groupname -> ".$filter->[0]."\n";
-			print OUTPUT pack("a32N", $filter->[0], 0);
-			$default++;
-		} else {
-			open FILTER, "./pfc '".escape_q($filter->[0])."' '".escape_q($filter->[1])."' |"
-				or die "Failed to run filter command for '".$filter->[0]."': $!\n";
-			while (<FILTER>) {
-				print OUTPUT $_;
-			}
-			close FILTER;
-			$? and die "Filter '".$filter->[0]."' did not compile.\n";
-		}
-	}
-}
diff --git a/package/wprobe/src/filter/pfc.c b/package/wprobe/src/filter/pfc.c
deleted file mode 100644
index 76fb1412aa..0000000000
--- a/package/wprobe/src/filter/pfc.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <pcap.h>
-#include <pcap-bpf.h>
-
-struct wprobe_filter_hdr {
-	char name[32];
-	uint32_t len;
-} hdr;
-
-int main (int argc, char ** argv)
-{
-    struct  bpf_program filter;
-    pcap_t  *pc;
-	int i;
-
-    if (argc != 3)
-    {
-		fprintf(stderr, "Usage: %s <name> <expression>\n", argv[0]);
-		return 1;
-    }
-
-    pc = pcap_open_dead(DLT_IEEE802_11_RADIO, 256);
-    if (pcap_compile(pc, &filter, argv[2], 1, 0) != 0)
-	{
-		pcap_perror(pc, argv[0]);
-		exit(1);
-	}
-
-	/* fix up for linux */
-	for (i = 0; i < filter.bf_len; i++) {
-		struct bpf_insn *bi = &filter.bf_insns[i];
-		switch(BPF_CLASS(bi->code)) {
-		case BPF_RET:
-			if (BPF_MODE(bi->code) == BPF_K) {
-				if (bi->k != 0)
-					bi->k = 65535;
-			}
-			break;
-		}
-		bi->code = ntohs(bi->code);
-		bi->k = ntohl(bi->k);
-	}
-
-	memset(&hdr, 0, sizeof(hdr));
-	strncpy(hdr.name, argv[1], sizeof(hdr.name));
-	hdr.len = htonl(filter.bf_len);
-	fwrite(&hdr, sizeof(hdr), 1, stdout);
-	fwrite(filter.bf_insns, 8, filter.bf_len, stdout);
-	fflush(stdout);
-
-    return 0;
-}
diff --git a/package/wprobe/src/kernel/Makefile b/package/wprobe/src/kernel/Makefile
deleted file mode 100644
index 2a9875311e..0000000000
--- a/package/wprobe/src/kernel/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-EXTRA_CFLAGS += -I.
-
-obj-m := wprobe.o wprobe-dummy.o
-
-wprobe-objs := wprobe-core.o
diff --git a/package/wprobe/src/kernel/linux/wprobe.h b/package/wprobe/src/kernel/linux/wprobe.h
deleted file mode 100644
index 901daf3d10..0000000000
--- a/package/wprobe/src/kernel/linux/wprobe.h
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * wprobe.h: API for the wireless probe interface
- * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __WPROBE_H
-#define __WPROBE_H
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#include <linux/if_ether.h>
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/filter.h>
-#include <net/genetlink.h>
-#endif
-
-/** 
- * enum wprobe_attr: netlink attribute list
- *
- * @WPROBE_ATTR_UNSPEC: unused
- *
- * @WPROBE_ATTR_INTERFACE: interface name to process query on (NLA_STRING)
- * @WPROBE_ATTR_MAC: mac address (used for wireless links) (NLA_STRING)
- * @WPROBE_ATTR_FLAGS: interface/link/attribute flags (see enum wprobe_flags) (NLA_U32)a
- * @WPROBE_ATTR_DURATION: sampling duration (in milliseconds) (NLA_MSECS) 
- *
- * @WPROBE_ATTR_ID: attribute id (NLA_U32)
- * @WPROBE_ATTR_NAME: attribute name (NLA_STRING)
- * @WPROBE_ATTR_TYPE: attribute type (NLA_U8)
- *
- * attribute values:
- *
- * @WPROBE_VAL_STRING: string value (NLA_STRING)
- * @WPROBE_VAL_S8: signed 8-bit integer (NLA_U8)
- * @WPROBE_VAL_S16: signed 16-bit integer (NLA_U16)
- * @WPROBE_VAL_S32: signed 32-bit integer (NLA_U32)
- * @WPROBE_VAL_S64: signed 64-bit integer (NLA_U64)
- * @WPROBE_VAL_U8: unsigned 8-bit integer (NLA_U8)
- * @WPROBE_VAL_U16: unsigned 16-bit integer (NLA_U16)
- * @WPROBE_VAL_U32: unsigned 32-bit integer (NLA_U32)
- * @WPROBE_VAL_U64: unsigned 64-bit integer (NLA_U64)
- *
- * statistics:
- * @WPROBE_VAL_SUM: sum of all samples
- * @WPROBE_VAL_SUM_SQ: sum of all samples^2
- * @WPROBE_VAL_SAMPLES: number of samples
- * @WPROBE_VAL_SCALE_TIME: last time the samples were scaled down
- *
- * configuration:
- * @WPROBE_ATTR_INTERVAL: (measurement interval in milliseconds) (NLA_MSECS)
- * @WPROBE_ATTR_SAMPLES_MIN: minimum samples to keep during inactivity (NLA_U32)
- * @WPROBE_ATTR_SAMPLES_MAX: maximum samples to keep before scaling down (NLA_U32)
- * @WPROBE_ATTR_SAMPLES_SCALE_M: multiplier for scaling down samples (NLA_U32)
- * @WPROBE_ATTR_SAMPLES_SCALE_D: divisor for scaling down samples (NLA_U32)
- *
- * @WPROBE_ATTR_LAST: unused
- */
-enum wprobe_attr {
-	/* query attributes */
-	WPROBE_ATTR_UNSPEC,
-	WPROBE_ATTR_INTERFACE,
-	WPROBE_ATTR_MAC,
-	WPROBE_ATTR_FLAGS,
-
-	/* response data */
-	WPROBE_ATTR_ID,
-	WPROBE_ATTR_NAME,
-	WPROBE_ATTR_TYPE,
-	WPROBE_ATTR_DURATION,
-
-	/* value type attributes */
-	WPROBE_VAL_STRING,
-	WPROBE_VAL_S8,
-	WPROBE_VAL_S16,
-	WPROBE_VAL_S32,
-	WPROBE_VAL_S64,
-	WPROBE_VAL_U8,
-	WPROBE_VAL_U16,
-	WPROBE_VAL_U32,
-	WPROBE_VAL_U64,
-
-	/* aggregates for statistics */
-	WPROBE_VAL_SUM,
-	WPROBE_VAL_SUM_SQ,
-	WPROBE_VAL_SAMPLES,
-	WPROBE_VAL_SCALE_TIME,
-
-	/* config attributes */
-	WPROBE_ATTR_INTERVAL,
-	WPROBE_ATTR_SAMPLES_MIN,
-	WPROBE_ATTR_SAMPLES_MAX,
-	WPROBE_ATTR_SAMPLES_SCALE_M,
-	WPROBE_ATTR_SAMPLES_SCALE_D,
-	WPROBE_ATTR_FILTER,
-
-	WPROBE_ATTR_FILTER_GROUP,
-	WPROBE_ATTR_RXCOUNT,
-	WPROBE_ATTR_TXCOUNT,
-
-	WPROBE_ATTR_LAST
-};
-
-
-/**
- * enum wprobe_cmd: netlink commands for interacting with wprobe
- *
- * @WPROBE_CMD_UNSPEC: unused
- *
- * @WPROBE_CMD_GET_LIST: get global/link property list
- * @WPROBE_CMD_GET_INFO: get global/link properties
- * @WPROBE_CMD_SET_FLAGS: set global/link flags
- * @WPROBE_CMD_MEASURE: take a snapshot of the current data
- * @WPROBE_CMD_GET_LINKS: get a list of links
- * @WPROBE_CMD_CONFIG: set config options
- * @WPROBE_CMD_GET_FILTER: get counters for active filters
- *
- * @WPROBE_CMD_LAST: unused
- * 
- * options for GET_INFO and SET_FLAGS:
- *   - mac address set: per-link
- *   - mac address unset: globalsa
- */
-enum wprobe_cmd {
-	WPROBE_CMD_UNSPEC,
-	WPROBE_CMD_GET_LIST,
-	WPROBE_CMD_GET_INFO,
-	WPROBE_CMD_SET_FLAGS,
-	WPROBE_CMD_MEASURE,
-	WPROBE_CMD_GET_LINKS,
-	WPROBE_CMD_CONFIG,
-	WPROBE_CMD_GET_FILTER,
-	WPROBE_CMD_LAST
-};
-
-/**
- * enum wprobe_flags: flags for wprobe links and items
- * @WPROBE_F_KEEPSTAT: keep statistics for this link/device
- * @WPROBE_F_RESET: reset statistics now
- * @WPROBE_F_NEWDATA: used to indicate that a value has been updated
- */
-enum wprobe_flags {
-	WPROBE_F_KEEPSTAT = (1 << 0),
-	WPROBE_F_RESET = (1 << 1),
-	WPROBE_F_NEWDATA = (1 << 2),
-};
-
-#ifdef __KERNEL__
-
-struct wprobe_link;
-struct wprobe_item;
-struct wprobe_source;
-struct wprobe_value;
-
-/**
- * struct wprobe_link - data structure describing a wireless link
- * @iface: pointer to the wprobe_iface that this link belongs to
- * @addr: BSSID of the remote link partner
- * @flags: link flags (see wprobe_flags)
- * @priv: user pointer
- *
- * @list: for internal use
- * @val: for internal use
- */
-struct wprobe_link {
-	struct list_head list;
-	struct wprobe_iface *iface;
-	char addr[ETH_ALEN];
-	u32 flags;
-	void *priv;
-	struct wprobe_value *val;
-};
-
-/** 
- * struct wprobe_item - data structure describing the format of wprobe_link::data or wprobe_iface::data
- * @name: name of the field
- * @type: data type of this field
- * @flags: measurement item flags (see wprobe_flags)
- */
-struct wprobe_item {
-	const char *name;
-	enum wprobe_attr type;
-	u32 flags;
-};
-
-struct wprobe_value {
-	bool pending;
-	union {
-		/*
-		 * the following are kept uppercase to allow
-		 * for automated checking against WPROBE_VAL_*
-		 * via BUG_ON()
-		 */
-		const char *STRING;
-		u8 U8;
-		u16 U16;
-		u32 U32;
-		u64 U64;
-		s8 S8;
-		s16 S16;
-		s32 S32;
-		s64 S64;
-	};
-	s64 s, ss;
-	unsigned int n;
-
-	/* timestamps */
-	u64 first, last;
-	u64 scale_timestamp;
-};
-
-struct wprobe_filter_item_hdr {
-	char name[32];
-	__be32 n_items;
-} __attribute__((packed));
-
-struct wprobe_filter_item {
-	struct wprobe_filter_item_hdr hdr;
-	struct sock_filter filter[];
-} __attribute__((packed));
-
-struct wprobe_filter_counter {
-	u64 tx;
-	u64 rx;
-};
-
-struct wprobe_filter_group {
-	const char *name;
-	int n_items;
-	struct wprobe_filter_item **items;
-	struct wprobe_filter_counter *counters;
-};
-
-struct wprobe_filter_hdr {
-	__u8 magic[4];
-	__u8 version;
-	__u8 hdrlen;
-	__u16 n_groups;
-} __attribute__((packed));
-
-struct wprobe_filter {
-	spinlock_t lock;
-	struct sk_buff *skb;
-	void *data;
-	int n_groups;
-	int hdrlen;
-	struct wprobe_filter_item **items;
-	struct wprobe_filter_counter *counters;
-	struct wprobe_filter_group groups[];
-};
-
-enum {
-	WPROBE_PKT_RX = 0x00,
-	WPROBE_PKT_TX = 0x10,
-};
-
-struct wprobe_wlan_hdr {
-	u16 len;
-	u8 snr;
-	u8 type;
-} __attribute__((packed));
-
-
-/**
- * struct wprobe_source - data structure describing a wireless interface
- *
- * @name: name of the interface
- * @addr: local mac address of the interface
- * @links: list of wireless links to poll
- * @link_items: description of the per-link data structure
- * @n_link_items: number of link description items
- * @global_items: description of the per-interface data structure
- * @n_global_items: number of per-interface description items
- * @sync_data: callback allowing the driver to prepare data for the wprobe poll
- *
- * @list: head for the list of interfaces
- * @priv: user pointer
- * @lock: spinlock protecting value data access
- * @val: internal use
- * @query_val: internal use
- *
- * if sync_data is NULL, wprobe assumes that it can access the data structure
- * at any time (in atomic context). if sync_data returns a negative error code,
- * the poll request will not be handled for the given link
- */
-struct wprobe_iface {
-	/* to be filled in by wprobe source drivers */
-	const char *name;
-	const char *addr;
-	const struct wprobe_item *link_items;
-	int n_link_items;
-	const struct wprobe_item *global_items;
-	int n_global_items;
-
-	int (*sync_data)(struct wprobe_iface *dev, struct wprobe_link *l,
-	                 struct wprobe_value *val, bool measure);
-	void *priv;
-
-	/* handled by the wprobe core */
-	struct list_head list;
-	struct list_head links;
-	spinlock_t lock;
-	struct wprobe_value *val;
-	struct wprobe_value *query_val;
-	struct wprobe_filter *active_filter;
-
-	u32 measure_interval;
-	struct timer_list measure_timer;
-
-	u32 scale_min;
-	u32 scale_max;
-	u32 scale_m;
-	u32 scale_d;
-};
-
-
-#define WPROBE_FILL_BEGIN(_ptr, _list) do {			\
-	struct wprobe_value *__val = (_ptr);			\
-	const struct wprobe_item *__item = _list;		\
-	u64 __msecs = jiffies_to_msecs(jiffies)
-
-#define WPROBE_SET(_idx, _type, _value)				\
-	if (__item[_idx].type != WPROBE_VAL_##_type) {		\
-		printk("ERROR: invalid data type at %s:%d\n", __FILE__, __LINE__); \
-		break;						\
-	}							\
-	__val[_idx].pending = true;				\
-	__val[_idx]._type = _value;				\
-	if (!__val[_idx].first)					\
-		__val[_idx].first = __msecs;			\
-	__val[_idx].first = __msecs
-
-#define WPROBE_FILL_END()					\
-} while(0)
-
-/**
- * wprobe_add_iface: register an interface with the wireless probe subsystem
- * @dev: wprobe_iface structure describing the interface
- */
-extern int __weak wprobe_add_iface(struct wprobe_iface *dev);
-
-/**
- * wprobe_remove_iface: deregister an interface from the wireless probe subsystem
- * @dev: wprobe_iface structure describing the interface
- */
-extern void __weak wprobe_remove_iface(struct wprobe_iface *dev);
-
-/**
- * wprobe_add_link: register a new wireless link
- * @dev: wprobe_iface structure describing the interface
- * @l: storage space for the wprobe_link structure
- * @addr: mac address of the new link
- *
- * the entire wprobe_link structure is overwritten by this function call
- */
-extern int __weak wprobe_add_link(struct wprobe_iface *dev, struct wprobe_link *l, const char *addr);
-
-/**
- * wprobe_remove_link: deregister a previously registered wireless link
- * @dev: wprobe_iface structure describing the interface
- * @l: wprobe_link data structure
- */
-extern void __weak wprobe_remove_link(struct wprobe_iface *dev, struct wprobe_link *l);
-
-/**
- * wprobe_update_stats: update statistics after sampling values
- * @dev: wprobe_iface structure describing the interface
- * @l: wprobe_link data structure
- *
- * if l == NULL, then the stats for globals are updated
- */
-extern void __weak wprobe_update_stats(struct wprobe_iface *dev, struct wprobe_link *l);
-
-/**
- * wprobe_add_frame: add frame for layer 2 analysis
- * @dev: wprobe_iface structure describing the interface
- * @hdr: metadata for the frame
- * @data: 802.11 header pointer
- * @len: length of the 802.11 header
- */
-extern int __weak wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, void *data, int len);
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/package/wprobe/src/kernel/wprobe-core.c b/package/wprobe/src/kernel/wprobe-core.c
deleted file mode 100644
index 6ec847a7a6..0000000000
--- a/package/wprobe/src/kernel/wprobe-core.c
+++ /dev/null
@@ -1,1164 +0,0 @@
-/*
- * wprobe-core.c: Wireless probe interface core
- * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/rcupdate.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-#include <linux/rculist.h>
-#else
-#include <linux/list.h>
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
-#include <linux/prefetch.h>
-#endif
-#include <linux/skbuff.h>
-#include <linux/wprobe.h>
-#include <linux/math64.h>
-
-#define static
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
-#define list_for_each_rcu(pos, head) \
-for (pos = rcu_dereference((head)->next); \
-prefetch(pos->next), pos != (head); \
-pos = rcu_dereference(pos->next))
-#endif
-
-#define WPROBE_MIN_INTERVAL		100 /* minimum measurement interval in msecs */
-#define WPROBE_MAX_FILTER_SIZE	1024
-#define WPROBE_MAX_FRAME_SIZE	1900
-
-static struct list_head wprobe_if;
-static spinlock_t wprobe_lock;
-
-static struct genl_family wprobe_fam = {
-	.id = GENL_ID_GENERATE,
-	.name = "wprobe",
-	.hdrsize = 0,
-	.version = 1,
-	/* only the first set of attributes is used for queries */
-	.maxattr = WPROBE_ATTR_LAST,
-};
-
-/* fake radiotap header */
-struct wprobe_rtap_hdr {
-	__u8 version;
-	__u8 padding;
-	__le16 len;
-	__le32 present;
-};
-
-static void wprobe_update_stats(struct wprobe_iface *dev, struct wprobe_link *l);
-static int wprobe_sync_data(struct wprobe_iface *dev, struct wprobe_link *l, bool query);
-static void wprobe_free_filter(struct wprobe_filter *f);
-
-int
-wprobe_add_link(struct wprobe_iface *s, struct wprobe_link *l, const char *addr)
-{
-	unsigned long flags;
-
-	INIT_LIST_HEAD(&l->list);
-	l->val = kzalloc(sizeof(struct wprobe_value) * s->n_link_items, GFP_ATOMIC);
-	if (!l->val)
-		return -ENOMEM;
-
-	l->iface = s;
-	memcpy(&l->addr, addr, ETH_ALEN);
-	spin_lock_irqsave(&wprobe_lock, flags);
-	list_add_tail_rcu(&l->list, &s->links);
-	spin_unlock_irqrestore(&wprobe_lock, flags);
-
-	return 0;
-}
-EXPORT_SYMBOL(wprobe_add_link);
-
-void
-wprobe_remove_link(struct wprobe_iface *s, struct wprobe_link *l)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&wprobe_lock, flags);
-	list_del_rcu(&l->list);
-	spin_unlock_irqrestore(&wprobe_lock, flags);
-	synchronize_rcu();
-	kfree(l->val);
-}
-EXPORT_SYMBOL(wprobe_remove_link);
-
-static void
-wprobe_measure_timer(unsigned long data)
-{
-	struct wprobe_iface *dev = (struct wprobe_iface *) data;
-
-	/* set next measurement interval */
-	mod_timer(&dev->measure_timer, jiffies +
-		msecs_to_jiffies(dev->measure_interval));
-
-	/* perform measurement */
-	wprobe_sync_data(dev, NULL, false);
-}
-
-int
-wprobe_add_iface(struct wprobe_iface *s)
-{
-	unsigned long flags;
-	int vsize;
-
-	/* reset only wprobe private area */
-	memset(&s->list, 0, sizeof(struct wprobe_iface) - offsetof(struct wprobe_iface, list));
-
-	BUG_ON(!s->name);
-	INIT_LIST_HEAD(&s->list);
-	INIT_LIST_HEAD(&s->links);
-	setup_timer(&s->measure_timer, wprobe_measure_timer, (unsigned long) s);
-
-	s->val = kzalloc(sizeof(struct wprobe_value) * s->n_global_items, GFP_ATOMIC);
-	if (!s->val)
-		goto error;
-
-	vsize = max(s->n_link_items, s->n_global_items);
-	s->query_val = kzalloc(sizeof(struct wprobe_value) * vsize, GFP_ATOMIC);
-	if (!s->query_val)
-		goto error;
-
-	/* initialize defaults to be able to handle overflow,
-	 * user space will need to handle this if it keeps an
-	 * internal histogram */
-	s->scale_min = 20;
-	s->scale_max = (1 << 31);
-
-	s->scale_m = 1;
-	s->scale_d = 10;
-
-	spin_lock_irqsave(&wprobe_lock, flags);
-	list_add_rcu(&s->list, &wprobe_if);
-	spin_unlock_irqrestore(&wprobe_lock, flags);
-
-	return 0;
-
-error:
-	if (s->val)
-		kfree(s->val);
-	return -ENOMEM;
-}
-EXPORT_SYMBOL(wprobe_add_iface);
-
-void
-wprobe_remove_iface(struct wprobe_iface *s)
-{
-	unsigned long flags;
-
-	BUG_ON(!list_empty(&s->links));
-
-	del_timer_sync(&s->measure_timer);
-	spin_lock_irqsave(&wprobe_lock, flags);
-	list_del_rcu(&s->list);
-	spin_unlock_irqrestore(&wprobe_lock, flags);
-
-	/* wait for all queries to finish before freeing the
-	 * temporary value storage buffer */
-	synchronize_rcu();
-
-	kfree(s->val);
-	kfree(s->query_val);
-	if (s->active_filter)
-		wprobe_free_filter(s->active_filter);
-}
-EXPORT_SYMBOL(wprobe_remove_iface);
-
-static struct wprobe_iface *
-wprobe_get_dev(struct nlattr *attr)
-{
-	struct wprobe_iface *dev = NULL;
-	struct wprobe_iface *p;
-	const char *name;
-	int i = 0;
-
-	if (!attr)
-		return NULL;
-
-	name = nla_data(attr);
-	list_for_each_entry_rcu(p, &wprobe_if, list) {
-		i++;
-		if (strcmp(name, p->name) != 0)
-			continue;
-
-		dev = p;
-		break;
-	}
-
-	return dev;
-}
-
-int
-wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, void *data, int len)
-{
-	struct wprobe_wlan_hdr *new_hdr;
-	struct wprobe_filter *f;
-	struct sk_buff *skb;
-	unsigned long flags;
-	int i, j;
-
-	rcu_read_lock();
-	f = rcu_dereference(dev->active_filter);
-	if (!f)
-		goto out;
-
-	spin_lock_irqsave(&f->lock, flags);
-
-	skb = f->skb;
-	skb->len = sizeof(struct wprobe_rtap_hdr);
-	skb->tail = skb->data + skb->len;
-	if (len + skb->len > WPROBE_MAX_FRAME_SIZE)
-		len = WPROBE_MAX_FRAME_SIZE - skb->len;
-
-	new_hdr = (struct wprobe_wlan_hdr *) skb_put(skb, f->hdrlen);
-	memcpy(new_hdr, hdr, sizeof(struct wprobe_wlan_hdr));
-	new_hdr->len = cpu_to_be16(new_hdr->len);
-
-	memcpy(skb_put(skb, len), data, len);
-
-	for(i = 0; i < f->n_groups; i++) {
-		struct wprobe_filter_group *fg = &f->groups[i];
-		bool found = false;
-		int def = -1;
-
-		for (j = 0; j < fg->n_items; j++) {
-			struct wprobe_filter_item *fi = fg->items[j];
-
-			if (!fi->hdr.n_items) {
-				def = j;
-				continue;
-			}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
-			if (sk_run_filter(skb, fi->filter) == 0)
-				continue;
-#else
-			if (sk_run_filter(skb, fi->filter, fi->hdr.n_items) == 0)
-				continue;
-#endif
-
-			found = true;
-			break;
-		}
-		if (!found && def >= 0) {
-			j = def;
-			found = true;
-		}
-		if (found) {
-			struct wprobe_filter_counter *c = &fg->counters[j];
-
-			if (hdr->type >= WPROBE_PKT_TX)
-				c->tx++;
-			else
-				c->rx++;
-		}
-	}
-
-	spin_unlock_irqrestore(&f->lock, flags);
-out:
-	rcu_read_unlock();
-	return 0;
-}
-EXPORT_SYMBOL(wprobe_add_frame);
-
-static int
-wprobe_sync_data(struct wprobe_iface *dev, struct wprobe_link *l, bool query)
-{
-	struct wprobe_value *val;
-	unsigned long flags;
-	int n, err;
-
-	if (l) {
-		n = dev->n_link_items;
-		val = l->val;
-	} else {
-		n = dev->n_global_items;
-		val = dev->val;
-	}
-
-	spin_lock_irqsave(&dev->lock, flags);
-	err = dev->sync_data(dev, l, val, !query);
-	if (err)
-		goto done;
-
-	if (query)
-		memcpy(dev->query_val, val, sizeof(struct wprobe_value) * n);
-
-	wprobe_update_stats(dev, l);
-done:
-	spin_unlock_irqrestore(&dev->lock, flags);
-	return 0;
-}
-EXPORT_SYMBOL(wprobe_sync_data);
-
-static void
-wprobe_scale_stats(struct wprobe_iface *dev, const struct wprobe_item *item,
-                   struct wprobe_value *val, int n)
-{
-	u64 scale_ts = jiffies_64;
-	int i;
-
-	for (i = 0; i < n; i++) {
-		if (!(item[i].flags & WPROBE_F_KEEPSTAT))
-			continue;
-
-		if (val[i].n <= dev->scale_min)
-			continue;
-
-		/* FIXME: div_s64 seems to be very imprecise here, even when
-		 * the values are scaled up */
-		val[i].s *= dev->scale_m;
-		val[i].s = div_s64(val[i].s, dev->scale_d);
-
-		val[i].ss *= dev->scale_m;
-		val[i].ss = div_s64(val[i].ss, dev->scale_d);
-
-		val[i].n = (val[i].n * dev->scale_m) / dev->scale_d;
-		val[i].scale_timestamp = scale_ts;
-	}
-}
-
-
-void
-wprobe_update_stats(struct wprobe_iface *dev, struct wprobe_link *l)
-{
-	const struct wprobe_item *item;
-	struct wprobe_value *val;
-	bool scale_stats = false;
-	int i, n;
-
-	if (l) {
-		n = dev->n_link_items;
-		item = dev->link_items;
-		val = l->val;
-	} else {
-		n = dev->n_global_items;
-		item = dev->global_items;
-		val = dev->val;
-	}
-
-	/* process statistics */
-	for (i = 0; i < n; i++) {
-		s64 v;
-
-		if (!val[i].pending)
-			continue;
-
-		val[i].n++;
-		if ((item[i].flags & WPROBE_F_KEEPSTAT) &&
-			(dev->scale_max > 0) && (val[i].n > dev->scale_max)) {
-			scale_stats = true;
-		}
-
-		switch(item[i].type) {
-		case WPROBE_VAL_S8:
-			v = val[i].S8;
-			break;
-		case WPROBE_VAL_S16:
-			v = val[i].S16;
-			break;
-		case WPROBE_VAL_S32:
-			v = val[i].S32;
-			break;
-		case WPROBE_VAL_S64:
-			v = val[i].S64;
-			break;
-		case WPROBE_VAL_U8:
-			v = val[i].U8;
-			break;
-		case WPROBE_VAL_U16:
-			v = val[i].U16;
-			break;
-		case WPROBE_VAL_U32:
-			v = val[i].U32;
-			break;
-		case WPROBE_VAL_U64:
-			v = val[i].U64;
-			break;
-		default:
-			continue;
-		}
-
-		val[i].s += v;
-		val[i].ss += v * v;
-		val[i].pending = false;
-	}
-	if (scale_stats)
-		wprobe_scale_stats(dev, item, val, n);
-}
-EXPORT_SYMBOL(wprobe_update_stats);
-
-static const struct nla_policy wprobe_policy[WPROBE_ATTR_LAST+1] = {
-	[WPROBE_ATTR_INTERFACE] = { .type = NLA_NUL_STRING },
-	[WPROBE_ATTR_MAC] = { .type = NLA_STRING },
-	[WPROBE_ATTR_FLAGS] = { .type = NLA_U32 },
-
-	/* config */
-	[WPROBE_ATTR_INTERVAL] = { .type = NLA_MSECS },
-	[WPROBE_ATTR_SAMPLES_MIN] = { .type = NLA_U32 },
-	[WPROBE_ATTR_SAMPLES_MAX] = { .type = NLA_U32 },
-	[WPROBE_ATTR_SAMPLES_SCALE_M] = { .type = NLA_U32 },
-	[WPROBE_ATTR_SAMPLES_SCALE_D] = { .type = NLA_U32 },
-	[WPROBE_ATTR_FILTER] = { .type = NLA_BINARY, .len = 32768 },
-};
-
-static bool
-wprobe_check_ptr(struct list_head *list, struct list_head *ptr)
-{
-	struct list_head *p;
-
-	list_for_each_rcu(p, list) {
-		if (ptr == p)
-			return true;
-	}
-	return false;
-}
-
-static bool
-wprobe_send_item_value(struct sk_buff *msg, struct netlink_callback *cb,
-                       struct wprobe_iface *dev, struct wprobe_link *l,
-                       const struct wprobe_item *item,
-                       int i, u32 flags)
-{
-	struct genlmsghdr *hdr;
-	struct wprobe_value *val = dev->query_val;
-	u64 time = val[i].last - val[i].first;
-
-	hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
-			&wprobe_fam, NLM_F_MULTI, WPROBE_CMD_GET_INFO);
-
-	NLA_PUT_U32(msg, WPROBE_ATTR_ID, i);
-	NLA_PUT_U32(msg, WPROBE_ATTR_FLAGS, flags);
-	NLA_PUT_U8(msg, WPROBE_ATTR_TYPE, item[i].type);
-	NLA_PUT_U64(msg, WPROBE_ATTR_DURATION, time);
-
-	switch(item[i].type) {
-	case WPROBE_VAL_S8:
-	case WPROBE_VAL_U8:
-		NLA_PUT_U8(msg, item[i].type, val[i].U8);
-		break;
-	case WPROBE_VAL_S16:
-	case WPROBE_VAL_U16:
-		NLA_PUT_U16(msg, item[i].type, val[i].U16);
-		break;
-	case WPROBE_VAL_S32:
-	case WPROBE_VAL_U32:
-		NLA_PUT_U32(msg, item[i].type, val[i].U32);
-		break;
-	case WPROBE_VAL_S64:
-	case WPROBE_VAL_U64:
-		NLA_PUT_U64(msg, item[i].type, val[i].U64);
-		break;
-	case WPROBE_VAL_STRING:
-		if (val[i].STRING)
-			NLA_PUT_STRING(msg, item[i].type, val[i].STRING);
-		else
-			NLA_PUT_STRING(msg, item[i].type, "");
-		/* bypass avg/stdev */
-		goto done;
-	default:
-		/* skip unknown values */
-		goto done;
-	}
-	if (item[i].flags & WPROBE_F_KEEPSTAT) {
-		NLA_PUT_U64(msg, WPROBE_VAL_SUM, val[i].s);
-		NLA_PUT_U64(msg, WPROBE_VAL_SUM_SQ, val[i].ss);
-		NLA_PUT_U32(msg, WPROBE_VAL_SAMPLES, (u32) val[i].n);
-		NLA_PUT_MSECS(msg, WPROBE_VAL_SCALE_TIME, val[i].scale_timestamp);
-	}
-done:
-	genlmsg_end(msg, hdr);
-	return true;
-
-nla_put_failure:
-	genlmsg_cancel(msg, hdr);
-	return false;
-}
-
-static bool
-wprobe_send_item_info(struct sk_buff *msg, struct netlink_callback *cb,
-                       struct wprobe_iface *dev,
-                       const struct wprobe_item *item, int i)
-{
-	struct genlmsghdr *hdr;
-
-	hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
-			&wprobe_fam, NLM_F_MULTI, WPROBE_CMD_GET_LIST);
-
-	if ((i == 0) && (dev->addr != NULL))
-		NLA_PUT(msg, WPROBE_ATTR_MAC, 6, dev->addr);
-	NLA_PUT_U32(msg, WPROBE_ATTR_ID, (u32) i);
-	NLA_PUT_STRING(msg, WPROBE_ATTR_NAME, item[i].name);
-	NLA_PUT_U8(msg, WPROBE_ATTR_TYPE, item[i].type);
-	NLA_PUT_U32(msg, WPROBE_ATTR_FLAGS, item[i].flags);
-	genlmsg_end(msg, hdr);
-	return true;
-
-nla_put_failure:
-	genlmsg_cancel(msg, hdr);
-	return false;
-}
-
-
-static struct wprobe_link *
-wprobe_find_link(struct wprobe_iface *dev, const char *mac)
-{
-	struct wprobe_link *l;
-
-	list_for_each_entry_rcu(l, &dev->links, list) {
-		if (!memcmp(l->addr, mac, 6))
-			return l;
-	}
-	return NULL;
-}
-
-static bool
-wprobe_dump_filter_group(struct sk_buff *msg, struct wprobe_filter_group *fg, struct netlink_callback *cb)
-{
-	struct genlmsghdr *hdr;
-	struct nlattr *group, *item;
-	int i;
-
-	hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
-			&wprobe_fam, NLM_F_MULTI, WPROBE_CMD_GET_FILTER);
-	if (!hdr)
-		return false;
-
-	NLA_PUT_STRING(msg, WPROBE_ATTR_NAME, fg->name);
-	group = nla_nest_start(msg, WPROBE_ATTR_FILTER_GROUP);
-	for (i = 0; i < fg->n_items; i++) {
-		struct wprobe_filter_item *fi = fg->items[i];
-		struct wprobe_filter_counter *fc = &fg->counters[i];
-
-		item = nla_nest_start(msg, WPROBE_ATTR_FILTER_GROUP);
-		NLA_PUT_STRING(msg, WPROBE_ATTR_NAME, fi->hdr.name);
-		NLA_PUT_U64(msg, WPROBE_ATTR_RXCOUNT, fc->rx);
-		NLA_PUT_U64(msg, WPROBE_ATTR_TXCOUNT, fc->tx);
-		nla_nest_end(msg, item);
-	}
-
-	nla_nest_end(msg, group);
-	genlmsg_end(msg, hdr);
-	return true;
-
-nla_put_failure:
-	genlmsg_cancel(msg, hdr);
-	return false;
-}
-
-static int
-wprobe_dump_filters(struct sk_buff *skb, struct netlink_callback *cb)
-{
-	struct wprobe_iface *dev = (struct wprobe_iface *)cb->args[0];
-	struct wprobe_filter *f;
-	int err = 0;
-	int i = 0;
-
-	if (!dev) {
-		err = nlmsg_parse(cb->nlh, GENL_HDRLEN + wprobe_fam.hdrsize,
-				wprobe_fam.attrbuf, wprobe_fam.maxattr, wprobe_policy);
-		if (err)
-			goto done;
-
-		dev = wprobe_get_dev(wprobe_fam.attrbuf[WPROBE_ATTR_INTERFACE]);
-		if (!dev) {
-			err = -ENODEV;
-			goto done;
-		}
-
-		cb->args[0] = (long) dev;
-		cb->args[1] = 0;
-	} else {
-		if (!wprobe_check_ptr(&wprobe_if, &dev->list)) {
-			err = -ENODEV;
-			goto done;
-		}
-	}
-
-	rcu_read_lock();
-	f = rcu_dereference(dev->active_filter);
-	if (!f)
-		goto abort;
-
-	for (i = cb->args[1]; i < f->n_groups; i++) {
-		if (unlikely(!wprobe_dump_filter_group(skb, &f->groups[i], cb)))
-			break;
-	}
-	cb->args[1] = i;
-abort:
-	rcu_read_unlock();
-	err = skb->len;
-done:
-	return err;
-}
-
-static bool
-wprobe_dump_link(struct sk_buff *msg, struct wprobe_link *l, struct netlink_callback *cb)
-{
-	struct genlmsghdr *hdr;
-
-	hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
-			&wprobe_fam, NLM_F_MULTI, WPROBE_CMD_GET_LINKS);
-	if (!hdr)
-		return false;
-
-	NLA_PUT(msg, WPROBE_ATTR_MAC, 6, l->addr);
-	genlmsg_end(msg, hdr);
-	return true;
-
-nla_put_failure:
-	genlmsg_cancel(msg, hdr);
-	return false;
-}
-
-static int
-wprobe_dump_links(struct sk_buff *skb, struct netlink_callback *cb)
-{
-	struct wprobe_iface *dev = (struct wprobe_iface *)cb->args[0];
-	struct wprobe_link *l;
-	int err = 0;
-	int i = 0;
-
-	if (!dev) {
-		err = nlmsg_parse(cb->nlh, GENL_HDRLEN + wprobe_fam.hdrsize,
-				wprobe_fam.attrbuf, wprobe_fam.maxattr, wprobe_policy);
-		if (err)
-			goto done;
-
-		dev = wprobe_get_dev(wprobe_fam.attrbuf[WPROBE_ATTR_INTERFACE]);
-		if (!dev) {
-			err = -ENODEV;
-			goto done;
-		}
-
-		cb->args[0] = (long) dev;
-	} else {
-		if (!wprobe_check_ptr(&wprobe_if, &dev->list)) {
-			err = -ENODEV;
-			goto done;
-		}
-	}
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(l, &dev->links, list) {
-		if (i < cb->args[1])
-			continue;
-
-		if (unlikely(!wprobe_dump_link(skb, l, cb)))
-			break;
-
-		i++;
-	}
-	cb->args[1] = i;
-	rcu_read_unlock();
-	err = skb->len;
-done:
-	return err;
-}
-
-#define WPROBE_F_LINK (1 << 31) /* for internal use */
-static int
-wprobe_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
-{
-	struct wprobe_iface *dev = (struct wprobe_iface *)cb->args[0];
-	struct wprobe_link *l = (struct wprobe_link *)cb->args[1];
-	struct wprobe_value *val;
-	const struct wprobe_item *item;
-	struct genlmsghdr *hdr;
-	unsigned long flags;
-	int cmd, n, i = cb->args[3];
-	u32	vflags = cb->args[2];
-	int err = 0;
-
-	hdr = (struct genlmsghdr *)nlmsg_data(cb->nlh);
-	cmd = hdr->cmd;
-
-	/* since the attribute value list might be too big for a single netlink
-	 * message, the device, link and offset get stored in the netlink callback.
-	 * if this is the first request, we need to do the full lookup for the device.
-	 *
-	 * access to the device and link structure is synchronized through rcu.
-	 */
-	rcu_read_lock();
-	if (!dev) {
-		err = nlmsg_parse(cb->nlh, GENL_HDRLEN + wprobe_fam.hdrsize,
-				wprobe_fam.attrbuf, wprobe_fam.maxattr, wprobe_policy);
-		if (err)
-			goto done;
-
-		err = -ENOENT;
-		dev = wprobe_get_dev(wprobe_fam.attrbuf[WPROBE_ATTR_INTERFACE]);
-		if (!dev)
-			goto done;
-
-		if (cmd == WPROBE_CMD_GET_INFO) {
-			if (wprobe_fam.attrbuf[WPROBE_ATTR_MAC]) {
-				l = wprobe_find_link(dev, nla_data(wprobe_fam.attrbuf[WPROBE_ATTR_MAC]));
-				if (!l)
-					goto done;
-
-				vflags = l->flags;
-			}
-
-			if (l) {
-				item = dev->link_items;
-				n = dev->n_link_items;
-				val = l->val;
-			} else {
-				item = dev->global_items;
-				n = dev->n_global_items;
-				val = dev->val;
-			}
-
-			/* sync data and move to temp storage for the query */
-			spin_lock_irqsave(&dev->lock, flags);
-			err = wprobe_sync_data(dev, l, true);
-			if (!err)
-				memcpy(dev->query_val, val, n * sizeof(struct wprobe_value));
-			spin_unlock_irqrestore(&dev->lock, flags);
-
-			if (err)
-				goto done;
-		}
-
-		if (wprobe_fam.attrbuf[WPROBE_ATTR_FLAGS])
-			vflags |= nla_get_u32(wprobe_fam.attrbuf[WPROBE_ATTR_FLAGS]);
-
-		if (wprobe_fam.attrbuf[WPROBE_ATTR_MAC])
-			vflags |= WPROBE_F_LINK;
-
-		cb->args[0] = (long) dev;
-		cb->args[1] = (long) l;
-		cb->args[2] = vflags;
-		cb->args[3] = 0;
-	} else {
-		/* when pulling pointers from the callback, validate them
-		 * against the list using rcu to make sure that we won't
-		 * dereference pointers to free'd memory after the last
-		 * grace period */
-		err = -ENOENT;
-		if (!wprobe_check_ptr(&wprobe_if, &dev->list))
-			goto done;
-
-		if (l && !wprobe_check_ptr(&dev->links, &l->list))
-			goto done;
-	}
-
-	if (vflags & WPROBE_F_LINK) {
-		item = dev->link_items;
-		n = dev->n_link_items;
-	} else {
-		item = dev->global_items;
-		n = dev->n_global_items;
-	}
-
-	err = 0;
-	switch(cmd) {
-	case WPROBE_CMD_GET_INFO:
-		while (i < n) {
-			if (!wprobe_send_item_value(skb, cb, dev, l, item, i, vflags))
-				break;
-			i++;
-		}
-		break;
-	case WPROBE_CMD_GET_LIST:
-		while (i < n) {
-			if (!wprobe_send_item_info(skb, cb, dev, item, i))
-				break;
-			i++;
-		}
-		break;
-	default:
-		err = -EINVAL;
-		goto done;
-	}
-	cb->args[3] = i;
-	err = skb->len;
-
-done:
-	rcu_read_unlock();
-	return err;
-}
-#undef WPROBE_F_LINK
-
-static int
-wprobe_update_auto_measurement(struct wprobe_iface *dev, u32 interval)
-{
-	if (interval && (interval < WPROBE_MIN_INTERVAL))
-		return -EINVAL;
-
-	if (!interval && dev->measure_interval)
-		del_timer_sync(&dev->measure_timer);
-
-	dev->measure_interval = interval;
-	if (!interval)
-		return 0;
-
-	/* kick of a new measurement immediately */
-	mod_timer(&dev->measure_timer, jiffies + 1);
-
-	return 0;
-}
-
-static int
-wprobe_measure(struct sk_buff *skb, struct genl_info *info)
-{
-	struct wprobe_iface *dev;
-	struct wprobe_link *l = NULL;
-	int err = -ENOENT;
-
-	rcu_read_lock();
-	dev = wprobe_get_dev(info->attrs[WPROBE_ATTR_INTERFACE]);
-	if (!dev)
-		goto done;
-
-	if (info->attrs[WPROBE_ATTR_MAC]) {
-		l = wprobe_find_link(dev, nla_data(wprobe_fam.attrbuf[WPROBE_ATTR_MAC]));
-		if (!l)
-			goto done;
-	}
-
-	err = wprobe_sync_data(dev, l, false);
-
-done:
-	rcu_read_unlock();
-	return err;
-}
-
-static int
-wprobe_check_filter(void *data, int datalen, int gs)
-{
-	struct wprobe_filter_item_hdr *hdr;
-	void *orig_data = data;
-	void *end = data + datalen;
-	int i, j, k, is, cur_is;
-
-	for (i = j = is = 0; i < gs; i++) {
-		hdr = data;
-		data += sizeof(*hdr);
-
-		if (data > end)
-			goto overrun;
-
-		hdr->name[31] = 0;
-		cur_is = be32_to_cpu(hdr->n_items);
-		hdr->n_items = cur_is;
-		is += cur_is;
-		for (j = 0; j < cur_is; j++) {
-			struct sock_filter *sf;
-			int n_items;
-
-			hdr = data;
-			data += sizeof(*hdr);
-			if (data > end)
-				goto overrun;
-
-			hdr->name[31] = 0;
-			n_items = be32_to_cpu(hdr->n_items);
-			hdr->n_items = n_items;
-
-			if (n_items > 1024)
-				goto overrun;
-
-			sf = data;
-			if (n_items > 0) {
-				for (k = 0; k < n_items; k++) {
-					sf->code = be16_to_cpu(sf->code);
-					sf->k = be32_to_cpu(sf->k);
-					sf++;
-				}
-				if (sk_chk_filter(data, n_items) != 0) {
-					printk("%s: filter check failed at group %d, item %d\n", __func__, i, j);
-					return 0;
-				}
-			}
-			data += n_items * sizeof(struct sock_filter);
-		}
-	}
-	return is;
-
-overrun:
-	printk(KERN_ERR "%s: overrun during filter check at group %d, item %d, offset=%d, len=%d\n", __func__, i, j, (data - orig_data), datalen);
-	return 0;
-}
-
-static void
-wprobe_free_filter(struct wprobe_filter *f)
-{
-	if (f->skb)
-		kfree_skb(f->skb);
-	if (f->data)
-		kfree(f->data);
-	if (f->items)
-		kfree(f->items);
-	if (f->counters)
-		kfree(f->counters);
-	kfree(f);
-}
-
-
-static int
-wprobe_set_filter(struct wprobe_iface *dev, void *data, int len)
-{
-	struct wprobe_filter_hdr *fhdr;
-	struct wprobe_rtap_hdr *rtap;
-	struct wprobe_filter *f;
-	int i, j, cur_is, is, gs;
-
-	if (len < sizeof(*fhdr))
-		return -EINVAL;
-
-	fhdr = data;
-	data += sizeof(*fhdr);
-	len -= sizeof(*fhdr);
-
-	if (memcmp(fhdr->magic, "WPFF", 4) != 0) {
-		printk(KERN_ERR "%s: filter rejected (invalid magic)\n", __func__);
-		return -EINVAL;
-	}
-
-	gs = be16_to_cpu(fhdr->n_groups);
-	is = wprobe_check_filter(data, len, gs);
-	if (is == 0)
-		return -EINVAL;
-
-	f = kzalloc(sizeof(struct wprobe_filter) +
-		gs * sizeof(struct wprobe_filter_group), GFP_ATOMIC);
-	if (!f)
-		return -ENOMEM;
-
-	f->skb = alloc_skb(WPROBE_MAX_FRAME_SIZE, GFP_ATOMIC);
-	if (!f->skb)
-		goto error;
-
-	f->data = kmalloc(len, GFP_ATOMIC);
-	if (!f->data)
-		goto error;
-
-	f->items = kzalloc(sizeof(struct wprobe_filter_item *) * is, GFP_ATOMIC);
-	if (!f->items)
-		goto error;
-
-	f->counters = kzalloc(sizeof(struct wprobe_filter_counter) * is, GFP_ATOMIC);
-	if (!f->counters)
-		goto error;
-
-	spin_lock_init(&f->lock);
-	memcpy(f->data, data, len);
-	f->n_groups = gs;
-
-	if (f->hdrlen < sizeof(struct wprobe_wlan_hdr))
-		f->hdrlen = sizeof(struct wprobe_wlan_hdr);
-
-	rtap = (struct wprobe_rtap_hdr *)skb_put(f->skb, sizeof(*rtap));
-	memset(rtap, 0, sizeof(*rtap));
-	rtap->len = cpu_to_le16(sizeof(struct wprobe_rtap_hdr) + f->hdrlen);
-	data = f->data;
-
-	cur_is = 0;
-	for (i = 0; i < gs; i++) {
-		struct wprobe_filter_item_hdr *hdr = data;
-		struct wprobe_filter_group *g = &f->groups[i];
-
-		data += sizeof(*hdr);
-		g->name = hdr->name;
-		g->items = &f->items[cur_is];
-		g->counters = &f->counters[cur_is];
-		g->n_items = hdr->n_items;
-
-		for (j = 0; j < g->n_items; j++) {
-			hdr = data;
-			f->items[cur_is++] = data;
-			data += sizeof(*hdr) + hdr->n_items * sizeof(struct sock_filter);
-		}
-	}
-	rcu_assign_pointer(dev->active_filter, f);
-	return 0;
-
-error:
-	wprobe_free_filter(f);
-	return -ENOMEM;
-}
-
-static int
-wprobe_set_config(struct sk_buff *skb, struct genl_info *info)
-{
-	struct wprobe_iface *dev;
-	unsigned long flags;
-	int err = -ENOENT;
-	u32 scale_min, scale_max;
-	u32 scale_m, scale_d;
-	struct nlattr *attr;
-	struct wprobe_filter *filter_free = NULL;
-
-	rcu_read_lock();
-	dev = wprobe_get_dev(info->attrs[WPROBE_ATTR_INTERFACE]);
-	if (!dev)
-		goto done_unlocked;
-
-	err = -EINVAL;
-	spin_lock_irqsave(&dev->lock, flags);
-	if (info->attrs[WPROBE_ATTR_MAC]) {
-		/* not supported yet */
-		goto done;
-	}
-
-	if (info->attrs[WPROBE_ATTR_FLAGS]) {
-		u32 flags = nla_get_u32(info->attrs[WPROBE_ATTR_FLAGS]);
-
-		if (flags & BIT(WPROBE_F_RESET)) {
-			struct wprobe_link *l;
-
-			memset(dev->val, 0, sizeof(struct wprobe_value) * dev->n_global_items);
-			list_for_each_entry_rcu(l, &dev->links, list) {
-				memset(l->val, 0, sizeof(struct wprobe_value) * dev->n_link_items);
-			}
-		}
-	}
-
-	if (info->attrs[WPROBE_ATTR_SAMPLES_MIN] ||
-		info->attrs[WPROBE_ATTR_SAMPLES_MAX]) {
-		if ((attr = info->attrs[WPROBE_ATTR_SAMPLES_MIN]))
-			scale_min = nla_get_u32(attr);
-		else
-			scale_min = dev->scale_min;
-
-		if ((attr = info->attrs[WPROBE_ATTR_SAMPLES_MAX]))
-			scale_max = nla_get_u32(attr);
-		else
-			scale_max = dev->scale_max;
-
-		if ((!scale_min && !scale_max) ||
-		    (scale_min && scale_max && (scale_min < scale_max))) {
-			dev->scale_min = scale_min;
-			dev->scale_max = scale_max;
-		} else {
-			goto done;
-		}
-	}
-
-	if (info->attrs[WPROBE_ATTR_SAMPLES_SCALE_M] &&
-		info->attrs[WPROBE_ATTR_SAMPLES_SCALE_D]) {
-
-		scale_m = nla_get_u32(info->attrs[WPROBE_ATTR_SAMPLES_SCALE_M]);
-		scale_d = nla_get_u32(info->attrs[WPROBE_ATTR_SAMPLES_SCALE_D]);
-
-		if (!scale_d || (scale_m > scale_d))
-			goto done;
-
-		dev->scale_m = scale_m;
-		dev->scale_d = scale_d;
-	}
-
-	if ((attr = info->attrs[WPROBE_ATTR_FILTER])) {
-		filter_free = rcu_dereference(dev->active_filter);
-		rcu_assign_pointer(dev->active_filter, NULL);
-		if (nla_len(attr) > 0)
-			wprobe_set_filter(dev, nla_data(attr), nla_len(attr));
-	}
-
-	err = 0;
-	if (info->attrs[WPROBE_ATTR_INTERVAL]) {
-		/* change of measurement interval requested */
-		err = wprobe_update_auto_measurement(dev,
-			(u32) nla_get_u64(info->attrs[WPROBE_ATTR_INTERVAL]));
-	}
-
-done:
-	spin_unlock_irqrestore(&dev->lock, flags);
-done_unlocked:
-	rcu_read_unlock();
-	if (filter_free) {
-		synchronize_rcu();
-		wprobe_free_filter(filter_free);
-	}
-	return err;
-}
-
-static struct genl_ops wprobe_ops[] = {
-	{
-		.cmd = WPROBE_CMD_GET_INFO,
-		.dumpit = wprobe_dump_info,
-		.policy = wprobe_policy,
-	},
-	{
-		.cmd = WPROBE_CMD_GET_LIST,
-		.dumpit = wprobe_dump_info,
-		.policy = wprobe_policy,
-	},
-	{
-		.cmd = WPROBE_CMD_MEASURE,
-		.doit = wprobe_measure,
-		.policy = wprobe_policy,
-	},
-	{
-		.cmd = WPROBE_CMD_GET_LINKS,
-		.dumpit = wprobe_dump_links,
-		.policy = wprobe_policy,
-	},
-	{
-		.cmd = WPROBE_CMD_CONFIG,
-		.doit = wprobe_set_config,
-		.policy = wprobe_policy,
-	},
-	{
-		.cmd = WPROBE_CMD_GET_FILTER,
-		.dumpit = wprobe_dump_filters,
-		.policy = wprobe_policy,
-	},
-};
-
-static void __exit
-wprobe_exit(void)
-{
-	BUG_ON(!list_empty(&wprobe_if));
-	genl_unregister_family(&wprobe_fam);
-}
-
-
-static int __init
-wprobe_init(void)
-{
-	int i, err;
-
-	spin_lock_init(&wprobe_lock);
-	INIT_LIST_HEAD(&wprobe_if);
-
-	err = genl_register_family(&wprobe_fam);
-	if (err)
-		return err;
-
-	for (i = 0; i < ARRAY_SIZE(wprobe_ops); i++) {
-		err = genl_register_ops(&wprobe_fam, &wprobe_ops[i]);
-		if (err)
-			goto error;
-	}
-
-	return 0;
-
-error:
-	genl_unregister_family(&wprobe_fam);
-	return err;
-}
-
-module_init(wprobe_init);
-module_exit(wprobe_exit);
-MODULE_LICENSE("GPL");
-
diff --git a/package/wprobe/src/kernel/wprobe-dummy.c b/package/wprobe/src/kernel/wprobe-dummy.c
deleted file mode 100644
index 4231223e0e..0000000000
--- a/package/wprobe/src/kernel/wprobe-dummy.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * wprobe-core.c: Wireless probe interface dummy driver
- * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/random.h>
-#include <linux/wprobe.h>
-
-static const char local_addr[] = "\x00\x13\x37\xba\xbe\x00";
-
-enum dummy_global_values {
-	DUMMY_GLOBAL_MEDIUM_BUSY
-};
-enum dummy_link_values {
-	DUMMY_LINK_SNR
-};
-
-struct wprobe_item dummy_perlink[] = {
-	[DUMMY_LINK_SNR] = {
-		.name = "snr",
-		.type = WPROBE_VAL_U8,
-		.flags = WPROBE_F_KEEPSTAT,
-	},
-};
-
-struct wprobe_item dummy_globals[] = {
-	[DUMMY_GLOBAL_MEDIUM_BUSY] = {
-		.name = "medium_busy",
-		.type = WPROBE_VAL_U8,
-		.flags = WPROBE_F_KEEPSTAT,
-	}
-};
-
-int dummy_sync(struct wprobe_iface *dev, struct wprobe_link *l, struct wprobe_value *val, bool measure)
-{
-	u8 intval = 0;
-
-	get_random_bytes(&intval, 1);
-	if (l) {
-		WPROBE_FILL_BEGIN(val, dummy_perlink);
-		WPROBE_SET(DUMMY_LINK_SNR, U8, (intval % 40));
-		WPROBE_FILL_END();
-	} else {
-		WPROBE_FILL_BEGIN(val, dummy_globals);
-		WPROBE_SET(DUMMY_GLOBAL_MEDIUM_BUSY, U8, (intval % 100));
-		WPROBE_FILL_END();
-	}
-	return 0;
-}
-
-static struct wprobe_iface dummy_dev = {
-	.name = "dummy",
-	.addr = local_addr,
-	.link_items = dummy_perlink,
-	.n_link_items = ARRAY_SIZE(dummy_perlink),
-	.global_items = dummy_globals,
-	.n_global_items = ARRAY_SIZE(dummy_globals),
-	.sync_data = dummy_sync,
-};
-
-static struct wprobe_link dummy_link;
-
-static int __init
-wprobe_dummy_init(void)
-{
-	wprobe_add_iface(&dummy_dev);
-	wprobe_add_link(&dummy_dev, &dummy_link, "\x00\x13\x37\xda\xda\x00");
-	return 0;
-}
-
-static void __exit
-wprobe_dummy_exit(void)
-{
-	wprobe_remove_link(&dummy_dev, &dummy_link);
-	wprobe_remove_iface(&dummy_dev);
-}
-
-module_init(wprobe_dummy_init);
-module_exit(wprobe_dummy_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/package/wprobe/src/user/Makefile b/package/wprobe/src/user/Makefile
deleted file mode 100644
index 01e83da3eb..0000000000
--- a/package/wprobe/src/user/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-include ../Makefile.inc
-
-CPPFLAGS += -I../kernel
-LDFLAGS =
-
-ifneq ($(HOST_OS),Linux)
-USE_LIBNL_MICRO=1
-else
-USE_LIBNL_MICRO=
-endif
-
-ifeq ($(USE_LIBNL_MICRO),1)
-LIBNL_PREFIX = /usr/local
-LIBNL = $(LIBNL_PREFIX)/lib/libnl-micro.a
-CPPFLAGS += -I$(LIBNL_PREFIX)/include/libnl-micro
-EXTRA_CFLAGS += -DNO_LOCAL_ACCESS
-else
-LIBNL = -lnl
-endif
-
-LIBM = -lm
-LIBS = $(LIBNL) $(LIBM)
-
-all: libwprobe.a wprobe-util
-
-libwprobe.a: wprobe-lib.o
-	rm -f $@
-	$(AR) rcu $@ $^
-	$(RANLIB) $@
-
-%.o: %.c
-	$(CC) $(WFLAGS) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) $<
-
-wprobe-util: wprobe-util.o wprobe-lib.o
-	$(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
-
-clean:
-	rm -f *.o *.a wprobe-util
diff --git a/package/wprobe/src/user/list.h b/package/wprobe/src/user/list.h
deleted file mode 100644
index 2959a061d3..0000000000
--- a/package/wprobe/src/user/list.h
+++ /dev/null
@@ -1,601 +0,0 @@
-#ifndef _LINUX_LIST_H
-#define _LINUX_LIST_H
-
-#include <stddef.h>
-/**
- * container_of - cast a member of a structure out to the containing structure
- * @ptr:	the pointer to the member.
- * @type:	the type of the container struct this is embedded in.
- * @member:	the name of the member within the struct.
- *
- */
-#ifndef container_of
-#define container_of(ptr, type, member) (			\
-	(type *)( (char *)ptr - offsetof(type,member) ))
-#endif
-
-
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct list_head {
-	struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
-	struct list_head name = LIST_HEAD_INIT(name)
-
-static inline void INIT_LIST_HEAD(struct list_head *list)
-{
-	list->next = list;
-	list->prev = list;
-}
-
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_add(struct list_head *new,
-			      struct list_head *prev,
-			      struct list_head *next)
-{
-	next->prev = new;
-	new->next = next;
-	new->prev = prev;
-	prev->next = new;
-}
-
-/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
-	__list_add(new, head, head->next);
-}
-
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
-	__list_add(new, head->prev, head);
-}
-
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
-	next->prev = prev;
-	prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty() on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void list_del(struct list_head *entry)
-{
-	__list_del(entry->prev, entry->next);
-	entry->next = NULL;
-	entry->prev = NULL;
-}
-
-/**
- * list_replace - replace old entry by new one
- * @old : the element to be replaced
- * @new : the new element to insert
- *
- * If @old was empty, it will be overwritten.
- */
-static inline void list_replace(struct list_head *old,
-				struct list_head *new)
-{
-	new->next = old->next;
-	new->next->prev = new;
-	new->prev = old->prev;
-	new->prev->next = new;
-}
-
-static inline void list_replace_init(struct list_head *old,
-					struct list_head *new)
-{
-	list_replace(old, new);
-	INIT_LIST_HEAD(old);
-}
-
-/**
- * list_del_init - deletes entry from list and reinitialize it.
- * @entry: the element to delete from the list.
- */
-static inline void list_del_init(struct list_head *entry)
-{
-	__list_del(entry->prev, entry->next);
-	INIT_LIST_HEAD(entry);
-}
-
-/**
- * list_move - delete from one list and add as another's head
- * @list: the entry to move
- * @head: the head that will precede our entry
- */
-static inline void list_move(struct list_head *list, struct list_head *head)
-{
-	__list_del(list->prev, list->next);
-	list_add(list, head);
-}
-
-/**
- * list_move_tail - delete from one list and add as another's tail
- * @list: the entry to move
- * @head: the head that will follow our entry
- */
-static inline void list_move_tail(struct list_head *list,
-				  struct list_head *head)
-{
-	__list_del(list->prev, list->next);
-	list_add_tail(list, head);
-}
-
-/**
- * list_is_last - tests whether @list is the last entry in list @head
- * @list: the entry to test
- * @head: the head of the list
- */
-static inline int list_is_last(const struct list_head *list,
-				const struct list_head *head)
-{
-	return list->next == head;
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
-{
-	return head->next == head;
-}
-
-/**
- * list_empty_careful - tests whether a list is empty and not being modified
- * @head: the list to test
- *
- * Description:
- * tests whether a list is empty _and_ checks that no other CPU might be
- * in the process of modifying either member (next or prev)
- *
- * NOTE: using list_empty_careful() without synchronization
- * can only be safe if the only activity that can happen
- * to the list entry is list_del_init(). Eg. it cannot be used
- * if another CPU could re-list_add() it.
- */
-static inline int list_empty_careful(const struct list_head *head)
-{
-	struct list_head *next = head->next;
-	return (next == head) && (next == head->prev);
-}
-
-static inline void __list_splice(struct list_head *list,
-				 struct list_head *head)
-{
-	struct list_head *first = list->next;
-	struct list_head *last = list->prev;
-	struct list_head *at = head->next;
-
-	first->prev = head;
-	head->next = first;
-
-	last->next = at;
-	at->prev = last;
-}
-
-/**
- * list_splice - join two lists
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- */
-static inline void list_splice(struct list_head *list, struct list_head *head)
-{
-	if (!list_empty(list))
-		__list_splice(list, head);
-}
-
-/**
- * list_splice_init - join two lists and reinitialise the emptied list.
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- *
- * The list at @list is reinitialised
- */
-static inline void list_splice_init(struct list_head *list,
-				    struct list_head *head)
-{
-	if (!list_empty(list)) {
-		__list_splice(list, head);
-		INIT_LIST_HEAD(list);
-	}
-}
-
-/**
- * list_entry - get the struct for this entry
- * @ptr:	the &struct list_head pointer.
- * @type:	the type of the struct this is embedded in.
- * @member:	the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
-	container_of(ptr, type, member)
-
-/**
- * list_first_entry - get the first element from a list
- * @ptr:	the list head to take the element from.
- * @type:	the type of the struct this is embedded in.
- * @member:	the name of the list_struct within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_first_entry(ptr, type, member) \
-	list_entry((ptr)->next, type, member)
-
-/**
- * list_for_each	-	iterate over a list
- * @pos:	the &struct list_head to use as a loop cursor.
- * @head:	the head for your list.
- */
-#define list_for_each(pos, head) \
-	for (pos = (head)->next; pos != (head); \
-        	pos = pos->next)
-
-/**
- * __list_for_each	-	iterate over a list
- * @pos:	the &struct list_head to use as a loop cursor.
- * @head:	the head for your list.
- *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no prefetching is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __list_for_each(pos, head) \
-	for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev	-	iterate over a list backwards
- * @pos:	the &struct list_head to use as a loop cursor.
- * @head:	the head for your list.
- */
-#define list_for_each_prev(pos, head) \
-	for (pos = (head)->prev; pos != (head); \
-        	pos = pos->prev)
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos:	the &struct list_head to use as a loop cursor.
- * @n:		another &struct list_head to use as temporary storage
- * @head:	the head for your list.
- */
-#define list_for_each_safe(pos, n, head) \
-	for (pos = (head)->next, n = pos->next; pos != (head); \
-		pos = n, n = pos->next)
-
-/**
- * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
- * @pos:	the &struct list_head to use as a loop cursor.
- * @n:		another &struct list_head to use as temporary storage
- * @head:	the head for your list.
- */
-#define list_for_each_prev_safe(pos, n, head) \
-	for (pos = (head)->prev, n = pos->prev; \
-	     pos != (head); \
-	     pos = n, n = pos->prev)
-
-/**
- * list_for_each_entry	-	iterate over list of given type
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- */
-#define list_for_each_entry(pos, head, member)				\
-	for (pos = list_entry((head)->next, typeof(*pos), member);	\
-	     &pos->member != (head); 	\
-	     pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_reverse - iterate backwards over list of given type.
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- */
-#define list_for_each_entry_reverse(pos, head, member)			\
-	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
-	     &pos->member != (head); 	\
-	     pos = list_entry(pos->member.prev, typeof(*pos), member))
-
-/**
- * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
- * @pos:	the type * to use as a start point
- * @head:	the head of the list
- * @member:	the name of the list_struct within the struct.
- *
- * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
- */
-#define list_prepare_entry(pos, head, member) \
-	((pos) ? : list_entry(head, typeof(*pos), member))
-
-/**
- * list_for_each_entry_continue - continue iteration over list of given type
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Continue to iterate over list of given type, continuing after
- * the current position.
- */
-#define list_for_each_entry_continue(pos, head, member) 		\
-	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
-	     &pos->member != (head);	\
-	     pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_continue_reverse - iterate backwards from the given point
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Start to iterate over list of given type backwards, continuing after
- * the current position.
- */
-#define list_for_each_entry_continue_reverse(pos, head, member)		\
-	for (pos = list_entry(pos->member.prev, typeof(*pos), member);	\
-	     &pos->member != (head);	\
-	     pos = list_entry(pos->member.prev, typeof(*pos), member))
-
-/**
- * list_for_each_entry_from - iterate over list of given type from the current point
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Iterate over list of given type, continuing from current position.
- */
-#define list_for_each_entry_from(pos, head, member) 			\
-	for (; &pos->member != (head);	\
-	     pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member)			\
-	for (pos = list_entry((head)->next, typeof(*pos), member),	\
-		n = list_entry(pos->member.next, typeof(*pos), member);	\
-	     &pos->member != (head); 					\
-	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_for_each_entry_safe_continue
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Iterate over list of given type, continuing after current point,
- * safe against removal of list entry.
- */
-#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
-	for (pos = list_entry(pos->member.next, typeof(*pos), member), 		\
-		n = list_entry(pos->member.next, typeof(*pos), member);		\
-	     &pos->member != (head);						\
-	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_for_each_entry_safe_from
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Iterate over list of given type from current point, safe against
- * removal of list entry.
- */
-#define list_for_each_entry_safe_from(pos, n, head, member) 			\
-	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
-	     &pos->member != (head);						\
-	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_for_each_entry_safe_reverse
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Iterate backwards over list of given type, safe against removal
- * of list entry.
- */
-#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
-	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
-		n = list_entry(pos->member.prev, typeof(*pos), member);	\
-	     &pos->member != (head); 					\
-	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
-
-/*
- * Double linked lists with a single pointer list head.
- * Mostly useful for hash tables where the two pointer list head is
- * too wasteful.
- * You lose the ability to access the tail in O(1).
- */
-
-struct hlist_head {
-	struct hlist_node *first;
-};
-
-struct hlist_node {
-	struct hlist_node *next, **pprev;
-};
-
-#define HLIST_HEAD_INIT { .first = NULL }
-#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
-#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
-static inline void INIT_HLIST_NODE(struct hlist_node *h)
-{
-	h->next = NULL;
-	h->pprev = NULL;
-}
-
-static inline int hlist_unhashed(const struct hlist_node *h)
-{
-	return !h->pprev;
-}
-
-static inline int hlist_empty(const struct hlist_head *h)
-{
-	return !h->first;
-}
-
-static inline void __hlist_del(struct hlist_node *n)
-{
-	struct hlist_node *next = n->next;
-	struct hlist_node **pprev = n->pprev;
-	*pprev = next;
-	if (next)
-		next->pprev = pprev;
-}
-
-static inline void hlist_del(struct hlist_node *n)
-{
-	__hlist_del(n);
-	n->next = NULL;
-	n->pprev = NULL;
-}
-
-static inline void hlist_del_init(struct hlist_node *n)
-{
-	if (!hlist_unhashed(n)) {
-		__hlist_del(n);
-		INIT_HLIST_NODE(n);
-	}
-}
-
-
-static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
-{
-	struct hlist_node *first = h->first;
-	n->next = first;
-	if (first)
-		first->pprev = &n->next;
-	h->first = n;
-	n->pprev = &h->first;
-}
-
-
-/* next must be != NULL */
-static inline void hlist_add_before(struct hlist_node *n,
-					struct hlist_node *next)
-{
-	n->pprev = next->pprev;
-	n->next = next;
-	next->pprev = &n->next;
-	*(n->pprev) = n;
-}
-
-static inline void hlist_add_after(struct hlist_node *n,
-					struct hlist_node *next)
-{
-	next->next = n->next;
-	n->next = next;
-	next->pprev = &n->next;
-
-	if(next->next)
-		next->next->pprev  = &next->next;
-}
-
-#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
-
-#define hlist_for_each(pos, head) \
-	for (pos = (head)->first; pos; pos = pos->next)
-
-#define hlist_for_each_safe(pos, n, head) \
-	for (pos = (head)->first; pos; pos = n)
-
-/**
- * hlist_for_each_entry	- iterate over list of given type
- * @tpos:	the type * to use as a loop cursor.
- * @pos:	the &struct hlist_node to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry(tpos, pos, head, member)			 \
-	for (pos = (head)->first; pos &&				 \
-		({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-	     pos = pos->next)
-
-/**
- * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
- * @tpos:	the type * to use as a loop cursor.
- * @pos:	the &struct hlist_node to use as a loop cursor.
- * @member:	the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry_continue(tpos, pos, member)		\
-	for (pos = (pos)->next; pos &&					\
-	     ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;});   \
-	     pos = pos->next)
-
-/**
- * hlist_for_each_entry_from - iterate over a hlist continuing from current point
- * @tpos:	the type * to use as a loop cursor.
- * @pos:	the &struct hlist_node to use as a loop cursor.
- * @member:	the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry_from(tpos, pos, member)			 \
-	for (; pos &&			 \
-		({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-	     pos = pos->next)
-
-/**
- * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @tpos:	the type * to use as a loop cursor.
- * @pos:	the &struct hlist_node to use as a loop cursor.
- * @n:		another &struct hlist_node to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry_safe(tpos, pos, n, head, member) 		 \
-	for (pos = (head)->first;					 \
-	     pos && ({ n = pos->next; 1; }) && 				 \
-		({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
-	     pos = n)
-
-#endif
diff --git a/package/wprobe/src/user/wprobe-lib.c b/package/wprobe/src/user/wprobe-lib.c
deleted file mode 100644
index 7a5460bb00..0000000000
--- a/package/wprobe/src/user/wprobe-lib.c
+++ /dev/null
@@ -1,1210 +0,0 @@
-/*
- * wprobe.c: Wireless probe user space library
- * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#define _ISOC99_SOURCE
-#define _BSD_SOURCE
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <math.h>
-#include <linux/wprobe.h>
-#include <netlink/netlink.h>
-#include <netlink/attr.h>
-#include <netlink/genl/genl.h>
-#ifndef NO_LOCAL_ACCESS 
-#include <netlink/genl/ctrl.h>
-#include <netlink/genl/family.h>
-#include <endian.h>
-#endif
-#include "wprobe.h"
-
-#define DEBUG 1
-#ifdef DEBUG
-#define DPRINTF(fmt, ...) fprintf(stderr, "%s(%d): " fmt, __func__, __LINE__, ##__VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
-
-#if defined(BYTE_ORDER) && !defined(__BYTE_ORDER)
-#define __LITTLE_ENDIAN LITTLE_ENDIAN
-#define __BIG_ENDIAN BIG_ENDIAN
-#define __BYTE_ORDER BYTE_ORDER
-#endif
-
-#ifndef __BYTE_ORDER
-#error Unknown endian type
-#endif
-
-#define WPROBE_MAX_MSGLEN	65536
-
-static inline __u16 __swab16(__u16 x)
-{
-	return x<<8 | x>>8;
-}
-
-static inline __u32 __swab32(__u32 x)
-{
-	return x<<24 | x>>24 |
-		(x & (__u32)0x0000ff00UL)<<8 |
-		(x & (__u32)0x00ff0000UL)>>8;
-}
-
-static inline __u64 __swab64(__u64 x)
-{
-	return x<<56 | x>>56 |
-		(x & (__u64)0x000000000000ff00ULL)<<40 |
-		(x & (__u64)0x0000000000ff0000ULL)<<24 |
-		(x & (__u64)0x00000000ff000000ULL)<< 8 |
-		(x & (__u64)0x000000ff00000000ULL)>> 8 |
-		(x & (__u64)0x0000ff0000000000ULL)>>24 |
-		(x & (__u64)0x00ff000000000000ULL)>>40;
-}
-
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define SWAP16(var) var = __swab16(var)
-#define SWAP32(var) var = __swab32(var)
-#define SWAP64(var) var = __swab64(var)
-#else
-#define SWAP16(var) do {} while(0)
-#define SWAP32(var) do {} while(0)
-#define SWAP64(var) do {} while(0)
-#endif
-
-int wprobe_port = 17990;
-static struct nlattr *tb[WPROBE_ATTR_LAST+1];
-static struct nla_policy attribute_policy[WPROBE_ATTR_LAST+1] = {
-	[WPROBE_ATTR_ID] = { .type = NLA_U32 },
-	[WPROBE_ATTR_MAC] = { .type = NLA_UNSPEC, .minlen = 6, .maxlen = 6 },
-	[WPROBE_ATTR_NAME] = { .type = NLA_STRING },
-	[WPROBE_ATTR_FLAGS] = { .type = NLA_U32 },
-	[WPROBE_ATTR_TYPE] = { .type = NLA_U8 },
-	[WPROBE_ATTR_FLAGS] = { .type = NLA_U32 },
-	[WPROBE_VAL_S8] = { .type = NLA_U8 },
-	[WPROBE_VAL_S16] = { .type = NLA_U16 },
-	[WPROBE_VAL_S32] = { .type = NLA_U32 },
-	[WPROBE_VAL_S64] = { .type = NLA_U64 },
-	[WPROBE_VAL_U8] = { .type = NLA_U8 },
-	[WPROBE_VAL_U16] = { .type = NLA_U16 },
-	[WPROBE_VAL_U32] = { .type = NLA_U32 },
-	[WPROBE_VAL_U64] = { .type = NLA_U64 },
-	[WPROBE_VAL_SUM] = { .type = NLA_U64 },
-	[WPROBE_VAL_SUM_SQ] = { .type = NLA_U64 },
-	[WPROBE_VAL_SAMPLES] = { .type = NLA_U32 },
-	[WPROBE_VAL_SCALE_TIME] = { .type = NLA_U64 },
-	[WPROBE_ATTR_INTERVAL] = { .type = NLA_U64 },
-	[WPROBE_ATTR_SAMPLES_MIN] = { .type = NLA_U32 },
-	[WPROBE_ATTR_SAMPLES_MAX] = { .type = NLA_U32 },
-	[WPROBE_ATTR_SAMPLES_SCALE_M] = { .type = NLA_U32 },
-	[WPROBE_ATTR_SAMPLES_SCALE_D] = { .type = NLA_U32 },
-	[WPROBE_ATTR_FILTER_GROUP] = { .type = NLA_NESTED },
-	[WPROBE_ATTR_RXCOUNT] = { .type = NLA_U64 },
-	[WPROBE_ATTR_TXCOUNT] = { .type = NLA_U64 },
-};
-
-typedef int (*wprobe_cb_t)(struct nl_msg *, void *);
-
-struct wprobe_iface_ops {
-	int (*send_msg)(struct wprobe_iface *dev, struct nl_msg *msg, wprobe_cb_t cb, void *arg);
-	void (*free)(struct wprobe_iface *dev);
-};
-
-struct wprobe_attr_cb {
-	struct list_head *list;
-	char *addr;
-};
-
-#define WPROBE_MAGIC_STR "WPROBE"
-struct wprobe_init_hdr {
-	struct {
-		char magic[sizeof(WPROBE_MAGIC_STR)];
-
-		/* protocol version */
-		uint8_t version;
-
-		/* extra header length (unused for now) */
-		uint16_t extra;
-	} pre __attribute__((packed));
-	union {
-		struct {
-			uint16_t genl_family;
-		} v0 __attribute__((packed));
-	};
-} __attribute__((packed));
-
-struct wprobe_msg_hdr {
-	__u16 status;
-	__u16 error;
-	__u32 len;
-};
-
-enum wprobe_resp_status {
-	WPROBE_MSG_DONE = 0,
-	WPROBE_MSG_DATA = 1,
-};
-
-static inline void
-wprobe_swap_msg_hdr(struct wprobe_msg_hdr *mhdr)
-{
-	SWAP16(mhdr->status);
-	SWAP16(mhdr->error);
-	SWAP32(mhdr->len);
-}
-
-static int
-save_attribute_handler(struct nl_msg *msg, void *arg)
-{
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	const char *name = "N/A";
-	struct wprobe_attribute *attr;
-	int type = 0;
-	struct wprobe_attr_cb *cb = arg;
-
-	nla_parse(tb, WPROBE_ATTR_LAST, genlmsg_attrdata(gnlh, 0),
-			genlmsg_attrlen(gnlh, 0), attribute_policy);
-
-	if (tb[WPROBE_ATTR_NAME])
-		name = nla_data(tb[WPROBE_ATTR_NAME]);
-
-	attr = malloc(sizeof(struct wprobe_attribute) + strlen(name) + 1);
-	if (!attr)
-		return -1;
-
-	memset(attr, 0, sizeof(struct wprobe_attribute));
-
-	if (tb[WPROBE_ATTR_ID])
-		attr->id = nla_get_u32(tb[WPROBE_ATTR_ID]);
-
-	if (tb[WPROBE_ATTR_MAC] && cb->addr)
-		memcpy(cb->addr, nla_data(tb[WPROBE_ATTR_MAC]), 6);
-
-	if (tb[WPROBE_ATTR_FLAGS])
-		attr->flags = nla_get_u32(tb[WPROBE_ATTR_FLAGS]);
-
-	if (tb[WPROBE_ATTR_TYPE])
-		type = nla_get_u8(tb[WPROBE_ATTR_TYPE]);
-
-	if ((type < WPROBE_VAL_STRING) ||
-		(type > WPROBE_VAL_U64))
-		type = 0;
-
-	attr->type = type;
-	strcpy(attr->name, name);
-	INIT_LIST_HEAD(&attr->list);
-	list_add(&attr->list, cb->list);
-	return 0;
-}
-
-static struct nl_msg *
-wprobe_new_msg(struct wprobe_iface *dev, int cmd, bool dump)
-{
-	struct nl_msg *msg;
-	uint32_t flags = 0;
-
-	msg = nlmsg_alloc_size(65536);
-	if (!msg)
-		return NULL;
-
-	if (dump)
-		flags |= NLM_F_DUMP;
-
-	genlmsg_put(msg, 0, 0, dev->genl_family,
-			0, flags, cmd, 0);
-
-	NLA_PUT_STRING(msg, WPROBE_ATTR_INTERFACE, dev->ifname);
-nla_put_failure:
-	return msg;
-}
-
-
-static int
-dump_attributes(struct wprobe_iface *dev, bool link, struct list_head *list, char *addr)
-{
-	struct nl_msg *msg;
-	struct wprobe_attr_cb cb;
-
-	cb.list = list;
-	cb.addr = addr;
-	msg = wprobe_new_msg(dev, WPROBE_CMD_GET_LIST, true);
-	if (!msg)
-		return -ENOMEM;
-
-	if (link)
-		NLA_PUT(msg, WPROBE_ATTR_MAC, 6, "\x00\x00\x00\x00\x00\x00");
-
-	return dev->ops->send_msg(dev, msg, save_attribute_handler, &cb);
-
-nla_put_failure:
-	nlmsg_free(msg);
-	return -EINVAL;
-}
-
-static struct wprobe_iface *
-wprobe_alloc_dev(void)
-{
-	struct wprobe_iface *dev;
-
-	dev = malloc(sizeof(struct wprobe_iface));
-	if (!dev)
-		return NULL;
-
-	memset(dev, 0, sizeof(struct wprobe_iface));
-
-	dev->interval = -1;
-	dev->scale_min = -1;
-	dev->scale_max = -1;
-	dev->scale_m = -1;
-	dev->scale_d = -1;
-	dev->sockfd = -1;
-
-	INIT_LIST_HEAD(&dev->global_attr);
-	INIT_LIST_HEAD(&dev->link_attr);
-	INIT_LIST_HEAD(&dev->links);
-	return dev;
-}
-
-static int
-wprobe_init_dev(struct wprobe_iface *dev)
-{
-	dump_attributes(dev, false, &dev->global_attr, NULL);
-	dump_attributes(dev, true, &dev->link_attr, NULL);
-	return 0;
-}
-
-#ifndef NO_LOCAL_ACCESS 
-static int n_devs = 0;
-static struct nl_sock *handle = NULL;
-static struct nl_cache *cache = NULL;
-static struct genl_family *family = NULL;
-
-static int
-error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
-{
-	int *ret = arg;
-	*ret = err->error;
-	return NL_STOP;
-}
-
-static int
-finish_handler(struct nl_msg *msg, void *arg)
-{
-	int *ret = arg;
-	*ret = 0;
-	return NL_SKIP;
-}
-
-static int
-ack_handler(struct nl_msg *msg, void *arg)
-{
-	int *ret = arg;
-	*ret = 0;
-	return NL_STOP;
-}
-
-static void
-wprobe_local_free(struct wprobe_iface *dev)
-{
-	/* should not happen */
-	if (n_devs == 0)
-		return;
-
-	if (--n_devs != 0)
-		return;
-
-	if (cache)
-		nl_cache_free(cache);
-	if (handle)
-		nl_socket_free(handle);
-	handle = NULL;
-	cache = NULL;
-}
-
-static int
-wprobe_local_init(void)
-{
-	int ret;
-
-	if (n_devs++ > 0)
-		return 0;
-
-	handle = nl_socket_alloc();
-	if (!handle) {
-		DPRINTF("Failed to create handle\n");
-		goto err;
-	}
-
-	if (genl_connect(handle)) {
-		DPRINTF("Failed to connect to generic netlink\n");
-		goto err;
-	}
-
-	ret = genl_ctrl_alloc_cache(handle, &cache);
-	if (ret < 0) {
-		DPRINTF("Failed to allocate netlink cache\n");
-		goto err;
-	}
-
-	family = genl_ctrl_search_by_name(cache, "wprobe");
-	if (!family) {
-		DPRINTF("wprobe API not present\n");
-		goto err;
-	}
-	return 0;
-
-err:
-	wprobe_local_free(NULL);
-	return -EINVAL;
-}
-
-
-static int
-wprobe_local_send_msg(struct wprobe_iface *dev, struct nl_msg *msg, wprobe_cb_t callback, void *arg)
-{
-	struct nl_cb *cb;
-	int err = 0;
-
-	cb = nl_cb_alloc(NL_CB_DEFAULT);
-	if (!cb)
-		goto out_no_cb;
-
-	if (callback)
-		nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, arg);
-
-	err = nl_send_auto_complete(handle, msg);
-	if (err < 0)
-		goto out;
-
-	err = 1;
-
-	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
-	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
-	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
-
-	while (err > 0)
-		nl_recvmsgs(handle, cb);
-
-out:
-	nl_cb_put(cb);
-out_no_cb:
-	nlmsg_free(msg);
-	return err;
-}
-
-static const struct wprobe_iface_ops wprobe_local_ops = {
-	.send_msg = wprobe_local_send_msg,
-	.free = wprobe_local_free,
-};
-
-struct wprobe_iface *
-wprobe_get_dev(const char *ifname)
-{
-	struct wprobe_iface *dev;
-
-	if (wprobe_local_init() != 0)
-		return NULL;
-
-	dev = wprobe_alloc_dev();
-	if (!dev)
-		goto error_alloc;
-
-	dev->ifname = strdup(ifname);
-	dev->ops = &wprobe_local_ops;
-	dev->genl_family = genl_family_get_id(family);
-
-	if (wprobe_init_dev(dev) < 0)
-		goto error;
-
-	return dev;
-
-error:
-	free(dev);
-error_alloc:
-	wprobe_local_free(NULL);
-	return NULL;
-}
-
-#endif
-
-static void swap_nlmsghdr(struct nlmsghdr *nlh)
-{
-	SWAP32(nlh->nlmsg_len);
-	SWAP16(nlh->nlmsg_type);
-	SWAP16(nlh->nlmsg_flags);
-	SWAP32(nlh->nlmsg_seq);
-	SWAP32(nlh->nlmsg_pid);
-}
-
-static void swap_genlmsghdr(struct genlmsghdr *gnlh)
-{
-#if 0 /* probably unnecessary */
-	SWAP16(gnlh->reserved);
-#endif
-}
-
-static void
-wprobe_swap_nested(void *data, int len, bool outgoing)
-{
-	void *end = data + len;
-
-	while (data < end) {
-		struct nlattr *nla = data;
-		unsigned int type, len;
-
-		if (!outgoing) {
-			SWAP16(nla->nla_len);
-			SWAP16(nla->nla_type);
-
-			/* required for further sanity checks */
-			if (data + nla->nla_len > end)
-				nla->nla_len = end - data;
-		}
-
-		len = NLA_ALIGN(nla->nla_len);
-		type = nla->nla_type & NLA_TYPE_MASK;
-
-		if (type <= WPROBE_ATTR_LAST) {
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-			switch(attribute_policy[type].type) {
-			case NLA_U16:
-				SWAP16(*(__u16 *)nla_data(nla));
-				break;
-			case NLA_U32:
-				SWAP32(*(__u32 *)nla_data(nla));
-				break;
-			case NLA_U64:
-				SWAP64(*(__u64 *)nla_data(nla));
-				break;
-			case NLA_NESTED:
-				wprobe_swap_nested(nla_data(nla), nla_len(nla), outgoing);
-				break;
-			}
-#endif
-		}
-		data += len;
-
-		if (outgoing) {
-			SWAP16(nla->nla_len);
-			SWAP16(nla->nla_type);
-		}
-		if (!nla->nla_len)
-			break;
-	}
-}
-
-static struct nl_msg *
-wprobe_msg_from_network(int socket, int len)
-{
-	struct genlmsghdr *gnlh;
-	struct nlmsghdr *nlh;
-	struct nl_msg *msg;
-	void *data;
-
-	msg = nlmsg_alloc_size(len + 32);
-	if (!msg)
-		return NULL;
-
-	nlh = nlmsg_hdr(msg);
-	if (read(socket, nlh, len) != len)
-		goto free;
-
-	swap_nlmsghdr(nlh);
-	if (nlh->nlmsg_len > len)
-		goto free;
-
-	gnlh = nlmsg_data(nlh);
-	swap_genlmsghdr(gnlh);
-
-	data = genlmsg_data(gnlh);
-	wprobe_swap_nested(data, genlmsg_len(gnlh), false);
-
-	return msg;
-free:
-	nlmsg_free(msg);
-	return NULL;
-}
-
-static int
-wprobe_msg_to_network(int socket, struct nl_msg *msg)
-{
-	struct nlmsghdr *nlh = nlmsg_hdr(msg);
-	struct wprobe_msg_hdr mhdr;
-	struct genlmsghdr *gnlh;
-	void *buf, *data;
-	int buflen, datalen;
-	int ret;
-
-	buflen = nlh->nlmsg_len;
-	buf = malloc(buflen);
-	if (!buf)
-		return -ENOMEM;
-
-	memset(&mhdr, 0, sizeof(mhdr));
-	mhdr.status = WPROBE_MSG_DATA;
-	mhdr.len = buflen;
-	wprobe_swap_msg_hdr(&mhdr);
-	ret = write(socket, &mhdr, sizeof(mhdr));
-	if (ret < 0)
-		goto out;
-
-	memcpy(buf, nlh, buflen);
-	nlh = buf;
-	gnlh = nlmsg_data(nlh);
-	data = genlmsg_data(gnlh);
-	datalen = genlmsg_len(gnlh);
-
-	wprobe_swap_nested(data, datalen, true);
-	swap_genlmsghdr(gnlh);
-	swap_nlmsghdr(nlh);
-	ret = write(socket, buf, buflen);
-
-out:
-	free(buf);
-
-	return ret;
-}
-
-static int
-wprobe_remote_send_msg(struct wprobe_iface *dev, struct nl_msg *msg, wprobe_cb_t callback, void *arg)
-{
-	struct wprobe_msg_hdr mhdr;
-	int msgs = 0;
-
-	wprobe_msg_to_network(dev->sockfd, msg);
-	nlmsg_free(msg);
-	do {
-		if (read(dev->sockfd, &mhdr, sizeof(mhdr)) != sizeof(mhdr)) {
-			DPRINTF("Failed to read response header\n");
-			return -1;
-		}
-		wprobe_swap_msg_hdr(&mhdr);
-
-		switch(mhdr.status) {
-		case WPROBE_MSG_DATA:
-			if (mhdr.len > WPROBE_MAX_MSGLEN) {
-				fprintf(stderr, "Invalid length in received response message.\n");
-				exit(1);
-			}
-
-			msg = wprobe_msg_from_network(dev->sockfd, mhdr.len);
-			if (!msg)
-				return -EINVAL;
-
-			msgs++;
-			callback(msg, arg);
-			nlmsg_free(msg);
-			break;
-		}
-	} while (mhdr.status != WPROBE_MSG_DONE);
-
-	if (mhdr.error)
-		return -mhdr.error;
-	else
-		return msgs;
-}
-
-
-static void
-wprobe_socket_dev_free(struct wprobe_iface *dev)
-{
-	if (dev->sockfd >= 0)
-		close(dev->sockfd);
-}
-
-static const struct wprobe_iface_ops wprobe_remote_ops = {
-	.send_msg = wprobe_remote_send_msg,
-	.free = wprobe_socket_dev_free,
-};
-
-
-#ifndef NO_LOCAL_ACCESS 
-int
-wprobe_server_init(int socket)
-{
-	struct wprobe_init_hdr hdr;
-	int ret;
-
-	ret = wprobe_local_init();
-	if (ret != 0)
-		return ret;
-
-	memset(&hdr, 0, sizeof(hdr));
-	memcpy(hdr.pre.magic, WPROBE_MAGIC_STR, sizeof(WPROBE_MAGIC_STR));
-	hdr.pre.version = 0;
-	hdr.v0.genl_family = genl_family_get_id(family);
-	SWAP16(hdr.v0.genl_family);
-	write(socket, (unsigned char *)&hdr, sizeof(hdr));
-
-	return 0;
-}
-
-static int
-wprobe_server_cb(struct nl_msg *msg, void *arg)
-{
-	int *socket = arg;
-	int ret;
-
-	ret = wprobe_msg_to_network(*socket, msg);
-	if (ret > 0)
-		ret = 0;
-
-	return ret;
-}
-
-
-int
-wprobe_server_handle(int socket)
-{
-	struct wprobe_msg_hdr mhdr;
-	struct nl_msg *msg;
-	int ret;
-
-	ret = read(socket, &mhdr, sizeof(mhdr));
-	if (ret != sizeof(mhdr)) {
-		if (ret <= 0)
-			return -1;
-
-		DPRINTF("Failed to read request header\n");
-		return -EINVAL;
-	}
-	wprobe_swap_msg_hdr(&mhdr);
-
-	switch(mhdr.status) {
-	case WPROBE_MSG_DATA:
-		if (mhdr.len > WPROBE_MAX_MSGLEN) {
-			DPRINTF("Invalid length in received response message.\n");
-			return -EINVAL;
-		}
-		msg = wprobe_msg_from_network(socket, mhdr.len);
-		break;
-	default:
-		DPRINTF("Invalid request header type\n");
-		return -ENOENT;
-	}
-
-	if (!msg) {
-		DPRINTF("Failed to get message\n");
-		return -EINVAL;
-	}
-
-	ret = wprobe_local_send_msg(NULL, msg, wprobe_server_cb, &socket);
-
-	memset(&mhdr, 0, sizeof(mhdr));
-	mhdr.status = WPROBE_MSG_DONE;
-	if (ret < 0)
-		mhdr.error = (uint16_t) -ret;
-
-	ret = write(socket, (unsigned char *)&mhdr, sizeof(mhdr));
-	if (ret > 0)
-		ret = 0;
-
-	return ret;
-}
-
-void
-wprobe_server_done(void)
-{
-	wprobe_local_free(NULL);
-}
-#endif
-
-struct wprobe_iface *
-wprobe_get_from_socket(int socket, const char *name)
-{
-	struct wprobe_iface *dev;
-	struct wprobe_init_hdr hdr;
-
-	dev = wprobe_alloc_dev();
-	if (!dev)
-		goto out;
-
-	dev->ops = &wprobe_remote_ops;
-	dev->sockfd = socket;
-	dev->ifname = strdup(name);
-
-	/* read version and header length */
-	if (read(socket, &hdr.pre, sizeof(hdr.pre)) != sizeof(hdr.pre)) {
-		DPRINTF("Could not read header\n");
-		goto error;
-	}
-
-	/* magic not found */
-	if (memcmp(hdr.pre.magic, WPROBE_MAGIC_STR, sizeof(hdr.pre.magic)) != 0) {
-		DPRINTF("Magic does not match\n");
-		goto error;
-	}
-
-	/* unsupported version */
-	if (hdr.pre.version != 0) {
-		DPRINTF("Protocol version does not match\n");
-		goto error;
-	}
-
-	if (read(socket, &hdr.v0, sizeof(hdr.v0)) != sizeof(hdr.v0)) {
-		DPRINTF("Could not read header data\n");
-		goto error;
-	}
-
-	SWAP16(hdr.pre.extra);
-	SWAP16(hdr.v0.genl_family);
-	dev->genl_family = hdr.v0.genl_family;
-
-	if (wprobe_init_dev(dev) < 0) {
-		DPRINTF("Could not initialize device\n");
-		goto error;
-	}
-
-out:
-	return dev;
-
-error:
-	wprobe_free_dev(dev);
-	return NULL;
-}
-
-struct wprobe_iface *
-wprobe_get_auto(const char *arg, char **err)
-{
-	static struct sockaddr_in sa;
-	static char errbuf[512];
-
-	struct wprobe_iface *dev = NULL;
-	struct hostent *h;
-	char *devstr = strdup(arg);
-	char *sep = NULL;
-	int sock = -1;
-	int len;
-
-	if (err)
-		*err = NULL;
-
-	sep = strchr(devstr, ':');
-	if (!sep) {
-#ifndef NO_LOCAL_ACCESS 
-		free(devstr);
-		return wprobe_get_dev(arg);
-#else
-		if (err)
-			*err = "Invalid argument";
-		goto out;
-#endif
-	}
-
-	*sep = 0;
-	sep++;
-
-	sock = socket(AF_INET, SOCK_STREAM, 0);
-	if (sock < 0)
-		goto syserr;
-
-	h = gethostbyname(devstr);
-	if (!h) {
-		sprintf(errbuf, "Host not found");
-		goto out_err;
-	}
-
-	memcpy(&sa.sin_addr, h->h_addr, h->h_length);
-	sa.sin_family = AF_INET;
-	sa.sin_port = htons(wprobe_port);
-	if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0)
-		goto syserr;
-
-	dev = wprobe_get_from_socket(sock, sep);
-	if (!dev) {
-		sprintf(errbuf, "wprobe connection initialization failed");
-		goto out_err;
-	}
-	goto out;
-
-syserr:
-	if (err) {
-		strcpy(errbuf, "Connection failed: ");
-		len = strlen(errbuf);
-		strerror_r(errno, errbuf + len, sizeof(errbuf) - len - 1);
-	}
-out_err:
-	if (err)
-		*err = errbuf;
-	if (sock >= 0)
-		close(sock);
-out:
-	if (devstr)
-		free(devstr);
-	return dev;
-}
-
-static void
-free_attr_list(struct list_head *list)
-{
-	struct wprobe_attribute *attr, *tmp;
-
-	list_for_each_entry_safe(attr, tmp, list, list) {
-		list_del(&attr->list);
-		free(attr);
-	}
-}
-
-void
-wprobe_free_dev(struct wprobe_iface *dev)
-{
-	if (dev->ops->free)
-		dev->ops->free(dev);
-	free_attr_list(&dev->global_attr);
-	free_attr_list(&dev->link_attr);
-	free((void *)dev->ifname);
-	free(dev);
-}
-
-static struct wprobe_link *
-get_link(struct list_head *list, const char *addr)
-{
-	struct wprobe_link *l;
-
-	list_for_each_entry(l, list, list) {
-		if (!memcmp(l->addr, addr, 6)) {
-			list_del_init(&l->list);
-			goto out;
-		}
-	}
-
-	/* no previous link found, allocate a new one */
-	l = malloc(sizeof(struct wprobe_link));
-	if (!l)
-		goto out;
-
-	memset(l, 0, sizeof(struct wprobe_link));
-	memcpy(l->addr, addr, sizeof(l->addr));
-	INIT_LIST_HEAD(&l->list);
-
-out:
-	return l;
-}
-
-struct wprobe_save_cb {
-	struct list_head *list;
-	struct list_head old_list;
-};
-
-static int
-save_link_handler(struct nl_msg *msg, void *arg)
-{
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	struct wprobe_link *link;
-	struct wprobe_save_cb *cb = arg;
-	const char *addr;
-
-	nla_parse(tb, WPROBE_ATTR_LAST, genlmsg_attrdata(gnlh, 0),
-			genlmsg_attrlen(gnlh, 0), attribute_policy);
-
-	if (!tb[WPROBE_ATTR_MAC] || (nla_len(tb[WPROBE_ATTR_MAC]) != 6))
-		return -1;
-
-	addr = nla_data(tb[WPROBE_ATTR_MAC]);
-	link = get_link(&cb->old_list, addr);
-	if (!link)
-		return -1;
-
-	if (tb[WPROBE_ATTR_FLAGS])
-		link->flags = nla_get_u32(tb[WPROBE_ATTR_FLAGS]);
-
-	list_add_tail(&link->list, cb->list);
-	return 0;
-}
-
-
-int
-wprobe_update_links(struct wprobe_iface *dev)
-{
-	struct wprobe_link *l, *tmp;
-	struct nl_msg *msg;
-	struct wprobe_save_cb cb;
-	int err;
-
-	INIT_LIST_HEAD(&cb.old_list);
-	list_splice_init(&dev->links, &cb.old_list);
-	cb.list = &dev->links;
-
-	msg = wprobe_new_msg(dev, WPROBE_CMD_GET_LINKS, true);
-	if (!msg)
-		return -ENOMEM;
-
-	err = dev->ops->send_msg(dev, msg, save_link_handler, &cb);
-	if (err < 0)
-		return err;
-
-	list_for_each_entry_safe(l, tmp, &cb.old_list, list) {
-		list_del(&l->list);
-		free(l);
-	}
-
-	return 0;
-}
-
-
-struct wprobe_filter_data
-{
-	wprobe_filter_cb cb;
-	void *arg;
-	struct wprobe_filter_item *buf;
-	int buflen;
-};
-
-static int
-dump_filter_handler(struct nl_msg *msg, void *arg)
-{
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	struct wprobe_filter_data *data = arg;
-	struct nlattr *p;
-	const char *name;
-	int count = 0;
-	int len;
-
-	nla_parse(tb, WPROBE_ATTR_LAST, genlmsg_attrdata(gnlh, 0),
-			genlmsg_attrlen(gnlh, 0), attribute_policy);
-
-	if (!tb[WPROBE_ATTR_NAME] || !tb[WPROBE_ATTR_FILTER_GROUP])
-		return -1;
-
-	name = nla_data(tb[WPROBE_ATTR_NAME]);
-	nla_for_each_nested(p, tb[WPROBE_ATTR_FILTER_GROUP], len) {
-		count++;
-	}
-
-	if (data->buflen < count) {
-		if (data->buf)
-			free(data->buf);
-		data->buflen = count;
-		data->buf = malloc(sizeof(struct wprobe_filter_item) * count);
-		memset(data->buf, 0, sizeof(struct wprobe_filter_item) * count);
-	}
-
-	count = 0;
-	nla_for_each_nested(p, tb[WPROBE_ATTR_FILTER_GROUP], len) {
-		struct wprobe_filter_item *fi;
-
-		nla_parse(tb, WPROBE_ATTR_LAST, nla_data(p),
-				nla_len(p), attribute_policy);
-
-		if (!tb[WPROBE_ATTR_NAME] || !tb[WPROBE_ATTR_RXCOUNT]
-				|| !tb[WPROBE_ATTR_TXCOUNT])
-			continue;
-
-		fi = &data->buf[count++];
-		strncpy(fi->name, nla_data(tb[WPROBE_ATTR_NAME]), sizeof(fi->name) - 1);
-		fi->name[sizeof(fi->name) - 1] = 0;
-		fi->rx = nla_get_u64(tb[WPROBE_ATTR_RXCOUNT]);
-		fi->tx = nla_get_u64(tb[WPROBE_ATTR_TXCOUNT]);
-	}
-	data->cb(data->arg, name, data->buf, count);
-
-	return 0;
-}
-
-int
-wprobe_dump_filters(struct wprobe_iface *dev, wprobe_filter_cb cb, void *arg)
-{
-	struct wprobe_filter_data data;
-	struct nl_msg *msg;
-	int err;
-
-	data.buf = 0;
-	data.buflen = 0;
-	data.cb = cb;
-	data.arg = arg;
-
-	msg = wprobe_new_msg(dev, WPROBE_CMD_GET_FILTER, true);
-	if (!msg)
-		return -ENOMEM;
-
-	err = dev->ops->send_msg(dev, msg, dump_filter_handler, &data);
-	if (err < 0)
-		return err;
-
-	return 0;
-}
-
-int
-wprobe_apply_config(struct wprobe_iface *dev)
-{
-	struct nl_msg *msg;
-
-	msg = wprobe_new_msg(dev, WPROBE_CMD_CONFIG, false);
-	if (!msg)
-		return -ENOMEM;
-
-	if (dev->interval >= 0)
-		NLA_PUT_MSECS(msg, WPROBE_ATTR_INTERVAL, dev->interval);
-
-	if (dev->filter_len < 0) {
-		NLA_PUT(msg, WPROBE_ATTR_FILTER, 0, NULL);
-		dev->filter_len = 0;
-	} else if (dev->filter && dev->filter_len > 0) {
-		NLA_PUT(msg, WPROBE_ATTR_FILTER, dev->filter_len, dev->filter);
-	}
-	dev->filter = NULL;
-
-	dev->ops->send_msg(dev, msg, NULL, NULL);
-	return 0;
-
-nla_put_failure:
-	nlmsg_free(msg);
-	return -ENOMEM;
-}
-
-int
-wprobe_measure(struct wprobe_iface *dev)
-{
-	struct nl_msg *msg;
-
-	msg = wprobe_new_msg(dev, WPROBE_CMD_MEASURE, false);
-	if (!msg)
-		return -ENOMEM;
-
-	dev->ops->send_msg(dev, msg, NULL, NULL);
-	return 0;
-}
-
-struct wprobe_request_cb {
-	struct list_head *list;
-	struct list_head old_list;
-	char *addr;
-};
-
-static int
-save_attrdata_handler(struct nl_msg *msg, void *arg)
-{
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	struct wprobe_request_cb *cb = arg;
-	struct wprobe_attribute *attr;
-	int type, id;
-
-	nla_parse(tb, WPROBE_ATTR_LAST, genlmsg_attrdata(gnlh, 0),
-			genlmsg_attrlen(gnlh, 0), attribute_policy);
-
-	if (!tb[WPROBE_ATTR_ID])
-		return -1;
-
-	if (!tb[WPROBE_ATTR_TYPE])
-		return -1;
-
-	id = nla_get_u32(tb[WPROBE_ATTR_ID]);
-	list_for_each_entry(attr, &cb->old_list, list) {
-		if (attr->id == id)
-			goto found;
-	}
-	/* not found */
-	return -1;
-
-found:
-	list_del_init(&attr->list);
-
-	type = nla_get_u8(tb[WPROBE_ATTR_TYPE]);
-	if (type != attr->type) {
-		DPRINTF("WARNING: type mismatch for %s attribute '%s' (%d != %d)\n",
-			(cb->addr ? "link" : "global"),
-			attr->name,
-			type, attr->type);
-		goto out;
-	}
-
-	if ((type < WPROBE_VAL_STRING) ||
-		(type > WPROBE_VAL_U64))
-		goto out;
-
-	memset(&attr->val, 0, sizeof(attr->val));
-
-#define HANDLE_INT_TYPE(_idx, _type) \
-	case WPROBE_VAL_S##_type: \
-	case WPROBE_VAL_U##_type: \
-		attr->val.U##_type = nla_get_u##_type(tb[_idx]); \
-		break
-
-	switch(type) {
-		HANDLE_INT_TYPE(type, 8);
-		HANDLE_INT_TYPE(type, 16);
-		HANDLE_INT_TYPE(type, 32);
-		HANDLE_INT_TYPE(type, 64);
-		case WPROBE_VAL_STRING:
-			/* unimplemented */
-			break;
-	}
-#undef HANDLE_TYPE
-
-	if (attr->flags & WPROBE_F_KEEPSTAT) {
-		if (tb[WPROBE_VAL_SUM])
-			attr->val.s = nla_get_u64(tb[WPROBE_VAL_SUM]);
-
-		if (tb[WPROBE_VAL_SUM_SQ])
-			attr->val.ss = nla_get_u64(tb[WPROBE_VAL_SUM_SQ]);
-
-		if (tb[WPROBE_VAL_SAMPLES])
-			attr->val.n = nla_get_u32(tb[WPROBE_VAL_SAMPLES]);
-
-		if (attr->val.n > 0) {
-			float avg = ((float) attr->val.s) / attr->val.n;
-			float stdev = sqrt((((float) attr->val.ss) / attr->val.n) - (avg * avg));
-			if (isnan(stdev))
-				stdev = 0.0f;
-			if (isnan(avg))
-				avg = 0.0f;
-			attr->val.avg = avg;
-			attr->val.stdev = stdev;
-		}
-	}
-
-out:
-	list_add_tail(&attr->list, cb->list);
-	return 0;
-}
-
-
-int
-wprobe_request_data(struct wprobe_iface *dev, const unsigned char *addr)
-{
-	struct wprobe_request_cb cb;
-	struct list_head *attrs;
-	struct nl_msg *msg;
-	int err;
-
-	msg = wprobe_new_msg(dev, WPROBE_CMD_GET_INFO, true);
-	if (!msg)
-		return -ENOMEM;
-
-	if (addr) {
-		attrs = &dev->link_attr;
-		NLA_PUT(msg, WPROBE_ATTR_MAC, 6, addr);
-	} else {
-		attrs = &dev->global_attr;
-	}
-
-	INIT_LIST_HEAD(&cb.old_list);
-	list_splice_init(attrs, &cb.old_list);
-	cb.list = attrs;
-
-	err = dev->ops->send_msg(dev, msg, save_attrdata_handler, &cb);
-	list_splice(&cb.old_list, attrs->prev);
-	return err;
-
-nla_put_failure:
-	nlmsg_free(msg);
-	return -ENOMEM;
-}
-
-
diff --git a/package/wprobe/src/user/wprobe-util.c b/package/wprobe/src/user/wprobe-util.c
deleted file mode 100644
index 654442f9cf..0000000000
--- a/package/wprobe/src/user/wprobe-util.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * wprobe-test.c: Wireless probe user space test code
- * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <arpa/inet.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <stdint.h>
-#include <getopt.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#include <linux/wprobe.h>
-#include "wprobe.h"
-
-static bool simple_mode = false;
-
-static const char *
-wprobe_dump_value(struct wprobe_attribute *attr)
-{
-	static char buf[128];
-
-#define HANDLE_TYPE(_type, _format) \
-	case WPROBE_VAL_##_type: \
-		snprintf(buf, sizeof(buf), _format, attr->val._type); \
-		break
-
-	switch(attr->type) {
-		HANDLE_TYPE(S8, "%d");
-		HANDLE_TYPE(S16, "%d");
-		HANDLE_TYPE(S32, "%d");
-		HANDLE_TYPE(S64, "%lld");
-		HANDLE_TYPE(U8, "%d");
-		HANDLE_TYPE(U16, "%d");
-		HANDLE_TYPE(U32, "%d");
-		HANDLE_TYPE(U64, "%lld");
-		case WPROBE_VAL_STRING:
-			/* FIXME: implement this */
-		default:
-			strncpy(buf, "<unknown>", sizeof(buf));
-			break;
-	}
-	if ((attr->flags & WPROBE_F_KEEPSTAT) &&
-		(attr->val.n > 0)) {
-		int len = strlen(buf);
-		if (simple_mode)
-			snprintf(buf + len, sizeof(buf) - len, ";%.02f;%.02f;%d;%lld;%lld", attr->val.avg, attr->val.stdev, attr->val.n, attr->val.s, attr->val.ss);
-		else
-			snprintf(buf + len, sizeof(buf) - len, " (avg: %.02f; stdev: %.02f, n=%d)", attr->val.avg, attr->val.stdev, attr->val.n);
-	}
-#undef HANDLE_TYPE
-
-	return buf;
-}
-
-
-static void
-wprobe_dump_data(struct wprobe_iface *dev)
-{
-	struct wprobe_attribute *attr;
-	struct wprobe_link *link;
-	bool first = true;
-
-	if (!simple_mode)
-		fprintf(stdout, "\n");
-	wprobe_request_data(dev, NULL);
-	list_for_each_entry(attr, &dev->global_attr, list) {
-		if (simple_mode) {
-			if (first)
-				fprintf(stdout, "[global]\n");
-			fprintf(stdout, "%s=%s\n", attr->name, wprobe_dump_value(attr));
-		} else {
-			fprintf(stdout, (first ?
-				"Global:            %s=%s\n" :
-				"                   %s=%s\n"),
-				attr->name,
-				wprobe_dump_value(attr)
-			);
-		}
-		first = false;
-	}
-
-	list_for_each_entry(link, &dev->links, list) {
-		first = true;
-		wprobe_request_data(dev, link->addr);
-		list_for_each_entry(attr, &dev->link_attr, list) {
-			if (first) {
-				fprintf(stdout,
-					(simple_mode ?
-					 "[%02x:%02x:%02x:%02x:%02x:%02x]\n%s=%s\n" :
-					 "%02x:%02x:%02x:%02x:%02x:%02x: %s=%s\n"),
-					link->addr[0], link->addr[1], link->addr[2],
-					link->addr[3], link->addr[4], link->addr[5],
-					attr->name,
-					wprobe_dump_value(attr));
-				first = false;
-			} else {
-				fprintf(stdout,
-					(simple_mode ? "%s=%s\n" :
-					 "                   %s=%s\n"),
-					attr->name,
-					wprobe_dump_value(attr));
-			}
-		}
-	}
-	fflush(stdout);
-}
-
-static const char *attr_typestr[] = {
-	[0] = "Unknown",
-	[WPROBE_VAL_STRING] = "String",
-	[WPROBE_VAL_U8] = "Unsigned 8 bit",
-	[WPROBE_VAL_U16] = "Unsigned 16 bit",
-	[WPROBE_VAL_U32] = "Unsigned 32 bit",
-	[WPROBE_VAL_U64] = "Unsigned 64 bit",
-	[WPROBE_VAL_S8] = "Signed 8 bit",
-	[WPROBE_VAL_S16] = "Signed 16 bit",
-	[WPROBE_VAL_S32] = "Signed 32 bit",
-	[WPROBE_VAL_S64] = "Signed 64 bit",
-};
-
-static int usage(const char *prog)
-{
-	fprintf(stderr,
-#ifndef NO_LOCAL_ACCESS
-		"Usage: %s <interface>|<host>:<device>|-P [options]\n"
-#else
-		"Usage: %s <host>:<device> [options]\n"
-#endif
-		"\n"
-		"Options:\n"
-		"  -a:            Print attributes\n"
-		"  -c:            Only apply configuration\n"
-		"  -d:            Delay between measurement dumps (in milliseconds, default: 1000)\n"
-		"                 A value of 0 (zero) prints once and exits; useful for scripts\n"
-		"  -f:            Dump contents of layer 2 filter counters during measurement\n"
-		"  -F <file>:     Apply layer 2 filters from <file>\n"
-		"  -h:            This help text\n"
-		"  -i <interval>: Set measurement interval\n"
-		"  -m:            Run measurement loop\n"
-		"  -p:            Set the TCP port for server/client (default: 17990)\n"
-#ifndef NO_LOCAL_ACCESS
-		"  -P:            Run in proxy mode (listen on network)\n"
-#endif
-		"\n"
-		, prog);
-	exit(1);
-}
-
-static void show_attributes(struct wprobe_iface *dev)
-{
-	struct wprobe_attribute *attr;
-	if (simple_mode)
-		return;
-	list_for_each_entry(attr, &dev->global_attr, list) {
-		fprintf(stdout, "Global attribute: '%s' (%s)\n",
-			attr->name, attr_typestr[attr->type]);
-	}
-	list_for_each_entry(attr, &dev->link_attr, list) {
-		fprintf(stdout, "Link attribute: '%s' (%s)\n",
-			attr->name, attr_typestr[attr->type]);
-	}
-}
-
-static void show_filter_simple(void *arg, const char *group, struct wprobe_filter_item *items, int n_items)
-{
-	int i;
-
-	fprintf(stdout, "[filter:%s]\n", group);
-	for (i = 0; i < n_items; i++) {
-		fprintf(stdout, "%s=%lld;%lld\n",
-			items[i].name, items[i].tx, items[i].rx);
-	}
-	fflush(stdout);
-}
-
-
-static void show_filter(void *arg, const char *group, struct wprobe_filter_item *items, int n_items)
-{
-	int i;
-	fprintf(stdout, "Filter group: '%s' (tx/rx)\n", group);
-	for (i = 0; i < n_items; i++) {
-		fprintf(stdout, " - %s (%lld/%lld)\n",
-			items[i].name, items[i].tx, items[i].rx);
-	}
-}
-
-static void loop_measurement(struct wprobe_iface *dev, bool print_filters, unsigned long delay)
-{
-	do {
-		wprobe_update_links(dev);
-		wprobe_dump_data(dev);
-		if (print_filters)
-			wprobe_dump_filters(dev, simple_mode ? show_filter_simple : show_filter, NULL);
-		usleep(delay * 1000);
-	}
-	while (delay);
-}
-
-static void set_filter(struct wprobe_iface *dev, const char *filename)
-{
-	unsigned char *buf = NULL;
-	unsigned int buflen = 0;
-	unsigned int len = 0;
-	int fd;
-
-	/* clear filter */
-	if (filename[0] == 0) {
-		dev->filter_len = -1;
-		return;
-	}
-
-	fd = open(filename, O_RDONLY);
-	if (fd < 0) {
-		perror("open filter");
-		return;
-	}
-
-	do {
-		int rlen;
-
-		if (!buf) {
-			len = 0;
-			buflen = 1024;
-			buf = malloc(1024);
-		} else {
-			buflen *= 2;
-			buf = realloc(buf, buflen);
-		}
-		rlen = read(fd, buf + len, buflen - len);
-		if (rlen < 0)
-			break;
-
-		len += rlen;
-	} while (len == buflen);
-
-	dev->filter = buf;
-	dev->filter_len = len;
-	close(fd);
-}
-
-#ifndef NO_LOCAL_ACCESS
-
-static void sigchld_handler(int s)
-{
-	while (waitpid(-1, NULL, WNOHANG) > 0);
-}
-
-static int run_proxy(int port)
-{
-	struct sockaddr_in sa;
-	struct sigaction sig;
-	int v = 1;
-	int s;
-
-	s = socket(AF_INET, SOCK_STREAM, 0);
-	if (s < 0) {
-		perror("socket");
-		return 1;
-	}
-
-	sig.sa_handler = sigchld_handler;  // Signal Handler fuer Zombie Prozesse
-	sigemptyset(&sig.sa_mask);
-	sig.sa_flags = SA_RESTART;
-	sigaction(SIGCHLD, &sig, NULL);
-
-	memset(&sa, 0, sizeof(sa));
-	sa.sin_family = AF_INET;
-	sa.sin_addr.s_addr = htonl(INADDR_ANY);
-	sa.sin_port = htons(wprobe_port);
-
-	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v));
-	if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
-		perror("bind");
-		return 1;
-	}
-	if (listen(s, 10)) {
-		perror("listen");
-		return 1;
-	}
-	while(1) {
-		unsigned int addrlen = sizeof(struct sockaddr_in);
-		int ret, c;
-
-		c = accept(s, (struct sockaddr *)&sa, &addrlen);
-		if (c < 0) {
-			if (errno == EINTR)
-				continue;
-
-			perror("accept");
-			return 1;
-		}
-		if (fork() == 0) {
-			/* close server socket, stdin, stdout, stderr */
-			close(s);
-			close(0);
-			close(1);
-			close(2);
-
-			wprobe_server_init(c);
-			do {
-				ret = wprobe_server_handle(c);
-			} while (ret >= 0);
-			wprobe_server_done();
-			close(c);
-			exit(0);
-		}
-		close(c);
-	}
-
-	return 0;
-}
-#endif
-
-int main(int argc, char **argv)
-{
-	struct wprobe_iface *dev = NULL;
-	const char *ifname;
-	const char *prog = argv[0];
-	char *err = NULL;
-	enum {
-		CMD_NONE,
-		CMD_CONFIG,
-		CMD_MEASURE,
-		CMD_PROXY,
-	} cmd = CMD_NONE;
-	const char *filter = NULL;
-	bool print_attributes = false;
-	bool print_filters = false;
-	unsigned long delay = 1000;
-	int interval = -1;
-	int ch;
-
-	if (argc < 2)
-		return usage(prog);
-
-#ifndef NO_LOCAL_ACCESS
-	if (!strcmp(argv[1], "-P")) {
-		while ((ch = getopt(argc - 1, argv + 1, "p:")) != -1) {
-			switch(ch) {
-			case 'p':
-				/* set port */
-				wprobe_port = strtoul(optarg, NULL, 0);
-				break;
-			default:
-				return usage(prog);
-			}
-		}
-		return run_proxy(wprobe_port);
-	}
-#endif
-
-	if (argv[1][0] == '-')
-		return usage(prog);
-
-	ifname = argv[1];
-	argv++;
-	argc--;
-
-	while ((ch = getopt(argc, argv, "acd:fF:hi:msp:")) != -1) {
-		switch(ch) {
-		case 'a':
-			print_attributes = true;
-			break;
-		case 'c':
-			cmd = CMD_CONFIG;
-			break;
-		case 'd':
-			delay = strtoul(optarg, NULL, 10);
-			break;
-		case 'm':
-			cmd = CMD_MEASURE;
-			break;
-		case 'i':
-			interval = strtoul(optarg, NULL, 10);
-			break;
-		case 'f':
-			print_filters = true;
-			break;
-		case 'F':
-			if (filter) {
-				fprintf(stderr, "Cannot set multiple filters\n");
-				return usage(prog);
-			}
-			filter = optarg;
-			break;
-		case 's':
-			simple_mode = true;
-			break;
-		case 'p':
-			/* set port */
-			wprobe_port = strtoul(optarg, NULL, 0);
-			break;
-		case 'h':
-		default:
-			usage(prog);
-			break;
-		}
-	}
-
-	dev = wprobe_get_auto(ifname, &err);
-	if (!dev || (list_empty(&dev->global_attr) &&
-		list_empty(&dev->link_attr))) {
-		if (err)
-			fprintf(stdout, "%s\n", err);
-		else
-			fprintf(stderr, "Interface '%s' not found\n", ifname);
-		return 1;
-	}
-
-	if (filter || interval >= 0) {
-		if (filter)
-			set_filter(dev, filter);
-		if (interval >= 0)
-			dev->interval = interval;
-
-		wprobe_apply_config(dev);
-	}
-
-	if (cmd != CMD_CONFIG) {
-		if (print_attributes)
-			show_attributes(dev);
-	}
-	if (cmd == CMD_MEASURE)
-		loop_measurement(dev, print_filters, delay);
-
-	wprobe_free_dev(dev);
-
-	return 0;
-}
diff --git a/package/wprobe/src/user/wprobe.h b/package/wprobe/src/user/wprobe.h
deleted file mode 100644
index 706facc808..0000000000
--- a/package/wprobe/src/user/wprobe.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * wprobe.h: Wireless probe user space library
- * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __WPROBE_USER_H
-#define __WPROBE_USER_H
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include "list.h"
-
-/**
- * struct wprobe_value: data structure for attribute values
- * @STRING: string value (currently unsupported)
- * @U8: unsigned 8-bit integer value
- * @U16: unsigned 16-bit integer value
- * @U32: unsigned 32-bit integer value
- * @U64: unsigned 64-bit integer value
- * @S8: signed 8-bit integer value
- * @S16: signed 16-bit integer value
- * @S32: signed 32-bit integer value
- * @S64: signed 64-bit integer value
- *
- * @n: number of sample values 
- * @avg: average value
- * @stdev: standard deviation
- * @s: sum of all sample values (internal use)
- * @ss: sum of all sample values squared (internal use)
- */
-struct wprobe_value {
-	/* attribute value */
-	union {
-		const char *STRING;
-		uint8_t U8;
-		uint16_t U16;
-		uint32_t U32;
-		uint64_t U64;
-		int8_t S8;
-		int16_t S16;
-		int32_t S32;
-		int64_t S64;
-	};
-	/* statistics */
-	int64_t s, ss;
-	float avg, stdev;
-	unsigned int n;
-};
-
-/**
- * struct wprobe_attribute: data structures for attribute descriptions
- * @list: linked list data structure for a list of attributes
- * @id: attribute id
- * @type: netlink type for the attribute (see kernel api documentation)
- * @flags: attribute flags (see kernel api documentation)
- * @val: cached version of the last netlink query, will be overwritten on each request
- * @name: attribute name
- */
-struct wprobe_attribute {
-	struct list_head list;
-	int id;
-	int type;
-	uint32_t flags;
-	struct wprobe_value val;
-	char name[];
-};
-
-/**
- * struct wprobe_link: data structure for the link description
- * @list: linked list data structure for a list of links 
- * @flags: link flags (see kernel api documentation)
- * @addr: mac address of the remote link partner
- */
-struct wprobe_link {
-	struct list_head list;
-	uint32_t flags;
-	unsigned char addr[6];
-};
-
-struct wprobe_filter_item {
-	char name[32];
-	uint64_t rx;
-	uint64_t tx;
-};
-
-struct wprobe_iface_ops;
-struct wprobe_iface {
-	const struct wprobe_iface_ops *ops;
-
-	int sockfd;
-	const char *ifname;
-	unsigned int genl_family;
-	char addr[6];
-
-	struct list_head global_attr;
-	struct list_head link_attr;
-	struct list_head links;
-
-	/* config */
-	int interval;
-	int scale_min;
-	int scale_max;
-	int scale_m;
-	int scale_d;
-
-	/* filter */
-	void *filter;
-
-	/* filter_len:
-	 *   set to -1 to drop the current filter
-	 *   automatically reset to 0 after config apply
-	 */
-	int filter_len;
-};
-
-typedef void (*wprobe_filter_cb)(void *arg, const char *group, struct wprobe_filter_item *items, int n_items);
-extern int wprobe_port;
-
-/**
- * wprobe_update_links: get a list of all link partners
- * @dev: wprobe device structure
- * @list: linked list for storing link descriptions
- *
- * when wprobe_update_links is called multiple times, the linked list 
- * is updated with new link partners, old entries are automatically expired
- */
-extern int wprobe_update_links(struct wprobe_iface *dev);
-
-/**
- * wprobe_dump_filters: dump all layer 2 filter counters
- * @dev: wprobe device structure
- * @cb: callback (called once per filter group)
- * @arg: user argument for the callback
- */
-extern int wprobe_dump_filters(struct wprobe_iface *dev, wprobe_filter_cb cb, void *arg);
-
-/**
- * wprobe_measure: start a measurement request for all global attributes
- * @dev: wprobe device structure
- *
- * not all attributes are automatically filled with data, since for some
- * it may be desirable to control the sampling interval from user space
- * you can use this function to do that.
- */
-extern int wprobe_measure(struct wprobe_iface *dev);
-
-/**
- * wprobe_get_dev: get a handle to a local wprobe device
- * @ifname: name of the wprobe interface
- *
- * queries the wprobe interface for all attributes
- * must be freed with wprobe_free_dev
- */
-extern struct wprobe_iface *wprobe_get_dev(const char *ifname);
-
-/**
- * wprobe_get_auto: get a handle to a local or remote wprobe device
- * @arg: pointer to the wprobe device, either <dev> (local) or <host>:<dev> (remote)
- */
-extern struct wprobe_iface *wprobe_get_auto(const char *arg, char **err);
-
-/**
- * wprobe_get_dev: free all device information
- * @dev: wprobe device structure
- */
-extern void wprobe_free_dev(struct wprobe_iface *dev);
-
-/**
- * wprobe_apply_config: apply configuration data
- * @dev: wprobe device structure
- *
- * uploads all configuration values from @dev that are not set to -1
- */
-extern int wprobe_apply_config(struct wprobe_iface *dev);
-
-/**
- * wprobe_request_data: request new sampling values for the given list of attributes
- * @dev: wprobe device structure
- * @addr: (optional) mac address of the link partner
- *
- * if addr is unset, global values are stored in the global attributes list
- * if addr is set, per-link values for the given address are stored in the link attributes list
- */
-extern int wprobe_request_data(struct wprobe_iface *dev, const unsigned char *addr);
-
-/**
- * wprobe_server_init: send a wprobe server init message to a server's client socket
- * @socket: socket of the connection to the client
- */
-extern int wprobe_server_init(int socket);
-
-/**
- * wprobe_server_handle: read a request from the client socket, process it, send the response
- * @socket: socket of the connection to the client
- */
-extern int wprobe_server_handle(int socket);
-
-/**
- * wprobe_server_done: release memory allocated for the server connection
- */
-extern void wprobe_server_done(void);
-
-#endif
-- 
2.30.2