summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreisnerd <eisnerd@localhost>2008-08-20 15:28:26 +0000
committereisnerd <eisnerd@localhost>2008-08-20 15:28:26 +0000
commitc662d16b8f08c70693d4588daad02b519345cf72 (patch)
tree740775bf046e5e3a27ac23fd9437ddbe0c470720 /sys-kernel
parentapp-emulation/virtualbox-guest-additions: add x11-apps/xrandr,x11-apps/xrefre... (diff)
downloadjokey-c662d16b8f08c70693d4588daad02b519345cf72.tar.gz
jokey-c662d16b8f08c70693d4588daad02b519345cf72.tar.bz2
jokey-c662d16b8f08c70693d4588daad02b519345cf72.zip
sys-kernel/thinkpad-sources: bump to 2.6.26-r1
svn path=/trunk/; revision=452
Diffstat (limited to 'sys-kernel')
-rw-r--r--sys-kernel/thinkpad-sources/ChangeLog20
-rw-r--r--sys-kernel/thinkpad-sources/Manifest53
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/00-bay-cleanup_exit-for-2.6.25.patch41
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/01-disk-protect-for-2.6.25.patch917
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/02-ipw2200-inject-for-2.6.25.patch77
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/03-libata-acpi_hotplug_fixups-for-2.6.25.patch215
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/04-linux-phc-0.3.1-for-2.6.25.patch526
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part1.patch113
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part2.patch220
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part3.patch146
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/kernel-2.6.25-export-init_mm.patch11
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/kernel-2.6.25-rcu-license.patch20
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/linux-2.6.25-iwl-merge.patch124255
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/pci-e_aspm_v3.5.patch1101
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/power-off-unused-ports.patch129
-rw-r--r--sys-kernel/thinkpad-sources/files/2.6.25-r1/vt-fix.patch146
-rw-r--r--sys-kernel/thinkpad-sources/files/configs/config-for-core-2.6.26-r1 (renamed from sys-kernel/thinkpad-sources/files/configs/config-for-core-2.6.25-r1)355
-rw-r--r--sys-kernel/thinkpad-sources/thinkpad-sources-2.6.26-r1.ebuild (renamed from sys-kernel/thinkpad-sources/thinkpad-sources-2.6.25-r1.ebuild)30
18 files changed, 241 insertions, 128134 deletions
diff --git a/sys-kernel/thinkpad-sources/ChangeLog b/sys-kernel/thinkpad-sources/ChangeLog
index 98131b2..38b5a7d 100644
--- a/sys-kernel/thinkpad-sources/ChangeLog
+++ b/sys-kernel/thinkpad-sources/ChangeLog
@@ -1,5 +1,25 @@
+ 20 Aug 2008; Florian Manschwetus <florianmanschwetus@gmx.de>
+ -files/2.6.25-r1/04-linux-phc-0.3.1-for-2.6.25.patch,
+ -files/2.6.25-r1/pci-e_aspm_v3.5.patch,
+ -files/configs/config-for-core-2.6.25-r1, -files/2.6.25-r1/vt-fix.patch,
+ -thinkpad-sources-2.6.25-r1.ebuild,
+ -files/2.6.25-r1/kernel-2.6.25-export-init_mm.patch,
+ -files/2.6.25-r1/linux-2.6.25-iwl-merge.patch,
+ -files/2.6.25-r1/00-bay-cleanup_exit-for-2.6.25.patch,
+ -files/2.6.25-r1/01-disk-protect-for-2.6.25.patch,
+ -files/2.6.25-r1/power-off-unused-ports.patch,
+ -files/2.6.25-r1/kernel-2.6.25-rcu-license.patch,
+ -files/2.6.25-r1/colored-printk-2.6.25.part1.patch,
+ -files/2.6.25-r1/colored-printk-2.6.25.part2.patch,
+ -files/2.6.25-r1/colored-printk-2.6.25.part3.patch,
+ -files/2.6.25-r1/03-libata-acpi_hotplug_fixups-for-2.6.25.patch,
+ -files/2.6.25-r1/02-ipw2200-inject-for-2.6.25.patch,
+ +thinkpad-sources-2.6.26-r1.ebuild,
+ +files/configs/config-for-core-2.6.26-r1, -files/2.6.25-r1:
+ bump to 2.6.26-r1
+
26 Jul 2008; Florian Manschwetus <florianmanschwetus@gmx.de>
-files/2.6.25/04-linux-phc-0.3.1-for-2.6.25.patch,
-files/2.6.25/vt-fix.patch,
diff --git a/sys-kernel/thinkpad-sources/Manifest b/sys-kernel/thinkpad-sources/Manifest
index 92f0d6c..6a6b8cc 100644
--- a/sys-kernel/thinkpad-sources/Manifest
+++ b/sys-kernel/thinkpad-sources/Manifest
@@ -1,37 +1,18 @@
-AUX 2.6.25-r1/00-bay-cleanup_exit-for-2.6.25.patch 1406 RMD160 5af97e44a193cfd3383e5719c708ad98249f2f7f SHA1 a147ba8383c9b2bd93125d3e8d52bda906c21fb2 SHA256 ed14a40a797b08ab08974af93af17d971bf056dee6c5a70d7cc82398ff37e6e3
-AUX 2.6.25-r1/01-disk-protect-for-2.6.25.patch 28041 RMD160 db29875229b28a95c68c1da982727a4e08f105ab SHA1 4799500b74091173d1c1f17a6f7df668f800a400 SHA256 a6ce92c1eac576709e4dd067663f6fed427dd7721b2633b1d954301300cb38b7
-AUX 2.6.25-r1/02-ipw2200-inject-for-2.6.25.patch 2182 RMD160 da365e1a73901e813ec9e73caca385dd5290d7b4 SHA1 67528e54a48288edee6f6c1642d73dee7a4146d2 SHA256 2e1016a2ebbde01ba34ea60b86ceec9082399afaaab0fd5ad03546a9a6b197e9
-AUX 2.6.25-r1/03-libata-acpi_hotplug_fixups-for-2.6.25.patch 5551 RMD160 437f60ab5e64bccfbe61872e09391cc7db10017e SHA1 6f630f7fe97927699d86501c2d893c5e03303cb3 SHA256 f2fa74439cdc5da81c053b2e6dc67b0b2b56bc7fa863f965c957ac3fc71ee43c
-AUX 2.6.25-r1/04-linux-phc-0.3.1-for-2.6.25.patch 15389 RMD160 2c33673ff0ec9021c1ec214b022fe73900c2811a SHA1 292f4a9874cb5905ef4feb06bfbcbc07e8dcdfca SHA256 1c00c0b22116b59bb4f77e5dcaad649120ad100eb4fded50924e76279d965049
-AUX 2.6.25-r1/colored-printk-2.6.25.part1.patch 3151 RMD160 15417414247874e7c47bc0ac44a1eb9565bebfae SHA1 5edeca7d5f8625f8fadcdfbdbac2d3480cba8d2c SHA256 290afd26e79fc4493de29ea20e86ea92f809da1e3db6c2e8a0edf9e0455fcea8
-AUX 2.6.25-r1/colored-printk-2.6.25.part2.patch 7972 RMD160 4ecc61abcf310a6013124fc1a49d046d7ab11fd6 SHA1 60a14368c01148f9ead5b4fe682d36e24a9e8933 SHA256 bbbff7947588f222610bd75be772351f9de08eb3df3ce4be20153bac7759578f
-AUX 2.6.25-r1/colored-printk-2.6.25.part3.patch 4150 RMD160 c1ffc2b7d28ac86b167179b9793bc2971648118d SHA1 4d8ee860b0d0b0951b34414f2591e725d88aa53a SHA256 e12e2aedff58baa521523160ad8a16fca8372b347c147d1c16263d3b6c79aab9
-AUX 2.6.25-r1/kernel-2.6.25-export-init_mm.patch 527 RMD160 09470465828a58d09f6a924e51ea9b34754cf108 SHA1 c0790545008f44287e8b8264c5d9919bf372e6c8 SHA256 4be986289e4032eecc8909cf636d3e47e66044d9bc40d36f4e10f8ba472ef203
-AUX 2.6.25-r1/kernel-2.6.25-rcu-license.patch 492 RMD160 375a45f3b55a6e591c872eb3213b1cb7d3f9cb3f SHA1 1aa76913d07870967fccc4deb235619ca2ce7297 SHA256 1e27b7522dd0a2ac2ee6913c4a1a403eff7e2652b9dfd4625f657f5ff2f8a75f
-AUX 2.6.25-r1/linux-2.6.25-iwl-merge.patch 3805877 RMD160 45f9a15c4dfc543b00132d2578327cb3184576a1 SHA1 5fa038f7a24d97f0b42bef54efb3857849ff9456 SHA256 409a56f78699c3386ebd7945940a36acf212d340ef5367aa5e4a567b5e762766
-AUX 2.6.25-r1/pci-e_aspm_v3.5.patch 32683 RMD160 8e126c0894d85f508ac190a6fecaa45fb7c56875 SHA1 697401cab1315e1c9025b8c17d0cfc78c59d2cda SHA256 89bf8956cc6cc0720bf0dad7107691a5bc5bd33da35fab1909e9f59f08e9ae5b
-AUX 2.6.25-r1/power-off-unused-ports.patch 4600 RMD160 9131091dee1ebe30259a0bce728206f0c36bd2a3 SHA1 4e15bb31848a503a3986b34eb22c6eb3b2efde2d SHA256 2621c0affed9e0ec966192ccfcc9b68644e68985434b0512202c849c44fe23c0
-AUX 2.6.25-r1/vt-fix.patch 6046 RMD160 6c018e117029867928713f9c1577f70a32a8541c SHA1 9da5b59769ead4d971def7a26d98cae3741f2474 SHA256 4e62d4467e3c11f3f3e37787e583ffefe333cbdf367cae2fef384673dcd31d47
-AUX 2.6.25/02-disk-protect-for-2.6.25.patch 28041 RMD160 db29875229b28a95c68c1da982727a4e08f105ab SHA1 4799500b74091173d1c1f17a6f7df668f800a400 SHA256 a6ce92c1eac576709e4dd067663f6fed427dd7721b2633b1d954301300cb38b7
-AUX 2.6.25/03-ipw2200-inject-for-2.6.25.patch 2182 RMD160 da365e1a73901e813ec9e73caca385dd5290d7b4 SHA1 67528e54a48288edee6f6c1642d73dee7a4146d2 SHA256 2e1016a2ebbde01ba34ea60b86ceec9082399afaaab0fd5ad03546a9a6b197e9
-AUX 2.6.25/04-linux-phc-0.3.1-for-2.6.25.patch 15389 RMD160 2c33673ff0ec9021c1ec214b022fe73900c2811a SHA1 292f4a9874cb5905ef4feb06bfbcbc07e8dcdfca SHA256 1c00c0b22116b59bb4f77e5dcaad649120ad100eb4fded50924e76279d965049
-AUX 2.6.25/colored-printk-2.6.25.part1.patch 3151 RMD160 15417414247874e7c47bc0ac44a1eb9565bebfae SHA1 5edeca7d5f8625f8fadcdfbdbac2d3480cba8d2c SHA256 290afd26e79fc4493de29ea20e86ea92f809da1e3db6c2e8a0edf9e0455fcea8
-AUX 2.6.25/colored-printk-2.6.25.part2.patch 7972 RMD160 4ecc61abcf310a6013124fc1a49d046d7ab11fd6 SHA1 60a14368c01148f9ead5b4fe682d36e24a9e8933 SHA256 bbbff7947588f222610bd75be772351f9de08eb3df3ce4be20153bac7759578f
-AUX 2.6.25/colored-printk-2.6.25.part3.patch 4150 RMD160 c1ffc2b7d28ac86b167179b9793bc2971648118d SHA1 4d8ee860b0d0b0951b34414f2591e725d88aa53a SHA256 e12e2aedff58baa521523160ad8a16fca8372b347c147d1c16263d3b6c79aab9
-AUX 2.6.25/kernel-2.6.25-export-init_mm.patch 527 RMD160 09470465828a58d09f6a924e51ea9b34754cf108 SHA1 c0790545008f44287e8b8264c5d9919bf372e6c8 SHA256 4be986289e4032eecc8909cf636d3e47e66044d9bc40d36f4e10f8ba472ef203
-AUX 2.6.25/kernel-2.6.25-rcu-license.patch 492 RMD160 375a45f3b55a6e591c872eb3213b1cb7d3f9cb3f SHA1 1aa76913d07870967fccc4deb235619ca2ce7297 SHA256 1e27b7522dd0a2ac2ee6913c4a1a403eff7e2652b9dfd4625f657f5ff2f8a75f
-AUX 2.6.25/pci-e_aspm_v3.5.patch 32683 RMD160 8e126c0894d85f508ac190a6fecaa45fb7c56875 SHA1 697401cab1315e1c9025b8c17d0cfc78c59d2cda SHA256 89bf8956cc6cc0720bf0dad7107691a5bc5bd33da35fab1909e9f59f08e9ae5b
-AUX 2.6.25/vt-fix.patch 6046 RMD160 6c018e117029867928713f9c1577f70a32a8541c SHA1 9da5b59769ead4d971def7a26d98cae3741f2474 SHA256 4e62d4467e3c11f3f3e37787e583ffefe333cbdf367cae2fef384673dcd31d47
-AUX configs/config-for-core-2.6.25 57068 RMD160 1cab7fb18d023e9aabd0df30db4a4825ee52eee2 SHA1 5b6ec9e157213243e444e1f899d1a097946a1eb7 SHA256 3b35429771d0f11d57c1ee57f5fee1db15622e7c1533f6330f6fd6e47945e190
-AUX configs/config-for-core-2.6.25-r1 57094 RMD160 f01c3aa0c94167bbdfcf83a7beb07d580c6a9896 SHA1 034bd829217395ba7fca5b1a12610f42e414c99e SHA256 79a765bff651f66342d3487a93b35b0290f3c40720f2eb92f0e25789474577f1
-DIST genpatches-2.6.25-4.base.tar.bz2 22088 RMD160 fd3a402ac7bd0f5fd7b623571b3e0452beb90fb3 SHA1 28c320f763160a428b466c4cdec3da7d17145e03 SHA256 7898eda702de503afe70b8d36e0594623453457cfa3fb7eabdd2b44de7f88fb0
-DIST genpatches-2.6.25-4.extras.tar.bz2 41717 RMD160 bc2f220a944f701d944061f11d633f2301139ccc SHA1 79d093c93ff1c76e98bff174d5b3c603cd1f0d7e SHA256 0cc8eaab5e746a7b514ee6c86e6ae986618ae4929c0a0c4a8e6098c9d3a43eae
-DIST genpatches-2.6.25-5.base.tar.bz2 43426 RMD160 f5350e3a3113fe3400ec7fc35541513b70681fea SHA1 06c2a7c9224507e89736f918bc9ca8caf6b36194 SHA256 9633e3480434abe8426465213b8af88cee3f2af015c12ebb7a0fdbe01ed45c1d
-DIST genpatches-2.6.25-5.extras.tar.bz2 41717 RMD160 bc2f220a944f701d944061f11d633f2301139ccc SHA1 79d093c93ff1c76e98bff174d5b3c603cd1f0d7e SHA256 0cc8eaab5e746a7b514ee6c86e6ae986618ae4929c0a0c4a8e6098c9d3a43eae
-DIST linux-2.6.25.tar.bz2 48601689 RMD160 cf3ed52f888fe9df7a93abe4fdc2f598e1ba0ce4 SHA1 aa6187a1c212dd2d8bd906b023fcefdcf711f35e SHA256 108b2a3f2b05c0e57d1d0977619525e46f8d4b425aef4b38b47dcf94292f2dd2
-DIST thinkpad-acpi-0.20-20080430_v2.6.25.1.patch.gz 14918 RMD160 ed6e3b8b686fe95b68536ef29359d82967542860 SHA1 bd92ed2559b03b09519ddf37cea73a1d3c7c7003 SHA256 57b8fdc3b44ed9c7255e979d3db3ff6d351adc436b3a973f87ebb333c800b001
-DIST tuxonice-3.0-rc7-for-2.6.25.patch.bz2 113685 RMD160 863ca8197572c2b1a14a0922fff21723fe23d455 SHA1 3629a55777740bda65d5df62309aa3e978e91f79 SHA256 1dbd15f436026c5383db42da7ce96708542b3dd42e17446bf809e5b8ce5c3bd2
-EBUILD thinkpad-sources-2.6.25-r1.ebuild 3804 RMD160 2aa72aa1408edbe18190b49088f4c6f6fb27d104 SHA1 301c54df7996a930e1caa17393f3d845a12ae578 SHA256 97165d253c3e67dcec32b4a5b8f5199a2853b3171e51f6128522c1d64bf7b5eb
-EBUILD thinkpad-sources-2.6.25.ebuild 3678 RMD160 27fdee391b1bb1fdccd28d3f8154d8ef85901fba SHA1 30d6f8171a05a2d08247ef9b2941ba9c54ffb402 SHA256 604ef6d2172c6a364f292509f88f32d16f56c584bba45d985447751f00426c1f
-MISC ChangeLog 5397 RMD160 a574661f7566b11a53d37268d3d427a8730bd28b SHA1 1e7f700d8ca5822ed9476e93922e3711917815c1 SHA256 0e889c947cdaf3d1e308ad825a28efaf6103ba2e9b4272e6fdf3475cc2f53743
+AUX 2.6.26/01-disk-protect-for-2.6.26.patch 28180 RMD160 b042f47b12c5bfb50fb88e10001c41aa3dd0492b SHA1 f73d961035a235d789b7457cb482e6c07f08458d SHA256 97196208e30eec2702ecb4f585419a44737401940d8cadea8c3e628681e81077
+AUX 2.6.26/02-ipw2200-inject-for-2.6.26.patch 2182 RMD160 159f8af4213996c36f22fbfc2f51627b9f73c259 SHA1 9126ce336d2e3c0ec77f29bbcf1f6a2a0c286b5d SHA256 22f7b0dd179ec1071853737af0a8f33eb7fe22f54e4291c91b69eab9c8e69c53
+AUX 2.6.26/colored-printk-2.6.26.patch 11265 RMD160 1e520168b8813754906513317f5c683dbec2b31b SHA1 d321509ccc286b29b8c0fac9ae18205705fea332 SHA256 e8afce0c43cd534a6f707dc9f8769d0ba03322efccd55e3dc3edc3375e44c4ba
+AUX 2.6.26/linux-phc-0.3.2-kernel-vanilla-2.6.26.patch 16865 RMD160 f5795436830ec3302c2a32c14a17ab52e089c8e2 SHA1 d24375cb01431b785228fae77682e9ee09286bf4 SHA256 e1fbb0909cee3cfb7623adae6ddd1384c95c977d111db8b5afc466aeab447f67
+AUX 2.6.26/power-off-unused-ports.patch 4600 RMD160 9131091dee1ebe30259a0bce728206f0c36bd2a3 SHA1 4e15bb31848a503a3986b34eb22c6eb3b2efde2d SHA256 2621c0affed9e0ec966192ccfcc9b68644e68985434b0512202c849c44fe23c0
+AUX configs/config-for-core-2.6.26 57774 RMD160 7b296c84f812f069236a8824c55c6a3bfb26da76 SHA1 ea61ebfcc1c66759f806d8a26384c8e026915ca9 SHA256 0b7425479eea885be675b68d733b385af5f20c26e6075394204ecf0a1e3ba95c
+AUX configs/config-for-core-2.6.26-r1 57803 RMD160 4c0af7d21a99b1733d0f4b1c2bdaac017056831c SHA1 6dca7e3718089e67118a9a98a043e0b192cca279 SHA256 0ce520ba91158b6ab9e595a0736759242806ff87afb67a4854e3e391370848e5
+DIST genpatches-2.6.26-1.base.tar.bz2 2747 RMD160 0bba41529ab51e9bf72bcca24fc5bdddfa8316be SHA1 36cb7c6300ed93d8db6e110ab5d823449c44cf0e SHA256 43fc0f34912623fc9102dabe627228cd993533d6a78162ee9817c0d994cfbf77
+DIST genpatches-2.6.26-1.extras.tar.bz2 41329 RMD160 247f08545525ebc0764d96be31f73cb3bc5366aa SHA1 4e46d6fc86530a535e2869dc255851a49fdb35e0 SHA256 4997e9dc128498286d10d54088f45be0ebdd98ec667723604d8760745b766716
+DIST genpatches-2.6.26-2.base.tar.bz2 47157 RMD160 953e262b25bab8bb32d530fee0a2eb97ba58fcce SHA1 d12da61c4a079a423d22526e7630ac35772e19a0 SHA256 ff9404e89067beeb6bae8a8eb1c1d362abb5d11c5b0a92abde67e30b856ea5ba
+DIST genpatches-2.6.26-2.extras.tar.bz2 41342 RMD160 1273b577012f1047f2dfff60afc2dfda16756c1e SHA1 cdf5503702804c09251b368ddf4118388020fda1 SHA256 e69683f14fc7155ba2b9049ad08dc59b91d3920caefab82f24d8f843fae350f0
+DIST linux-2.6.26.tar.bz2 49441874 RMD160 57c37e81afa48e7c05e1a933d390a12ac2921255 SHA1 3f44384bf84f27add3b6c43ec68f974d7f7e9c67 SHA256 666488e2511393fdb901eaf1e67275bcc38ab37c930e8a9adb290a95c1721a2a
+DIST thinkpad-acpi-0.21-20080703_v2.6.26-rc8.patch.gz 20013 RMD160 6bec127ca35df332f8b9fb0674bbd6ff9bf7177f SHA1 d847382e433896280ac4ae077f37060c30c73d60 SHA256 8cce502cfbebe6521372763410d7a31740176c747076ad0ed4b01aa71ab347c7
+DIST tuxonice-3.0-rc7a-for-2.6.26.patch.bz2 114165 RMD160 d20a16d73b26ca9ff685a7c0d25b903faf3b8b69 SHA1 6bbd5233740f4d5b4ceb2af0294286a4cd8a9fa7 SHA256 1969b906db3bf478d684e89f5395df69fa9142db6bae56a7046b42adae5c381b
+EBUILD thinkpad-sources-2.6.26-r1.ebuild 3428 RMD160 e44f3d850b0bc924eabd0cc62e72991528831159 SHA1 aa9e788124fbf03cfa8daeca2c186820acbc101c SHA256 3e5bddd4effbce7221e86be5d7bd971e9413ff849a668ea5c6f11263af2b1c88
+EBUILD thinkpad-sources-2.6.26.ebuild 3614 RMD160 55b8d77caf19cb8dbc7a9eb9631294db575e666c SHA1 fa90c42ad43706d481693c53a0db5c9a11e90b18 SHA256 4222e2a740bc28cfcd258b47186c419e6abc20bbd3b75e06f59c02fd82219eb2
+MISC ChangeLog 7304 RMD160 50202cccd574a850b7535b1f502fa2ec8c7776c8 SHA1 a6779ae173d5fcdab78f2e13f0399e4cfc640069 SHA256 213074a0a0e148df338ce97290e4207971320bbfdae2b5ff0caa7745624ba708
MISC metadata.xml 284 RMD160 5062b08f804b7eaf9e1765c0d38b7fc95bc467e4 SHA1 687ba9103e597aad8a7231ff9a470d841f7121df SHA256 6ca83c8927bd3516baac49bc9ea82ddbeeddbe38a5a98b637d6eb1f1d436c84a
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/00-bay-cleanup_exit-for-2.6.25.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/00-bay-cleanup_exit-for-2.6.25.patch
deleted file mode 100644
index d8c36a1..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/00-bay-cleanup_exit-for-2.6.25.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-If acpi_install_notify_handler() for a bay device fails, the bay driver is
-superfluous. Most likely, another driver (like libata) is already caring
-about this device anyway. Furthermore,
-register_hotplug_dock_device(acpi_handle) from the dock driver must not be
-called twice with the same handler. This would result in an endless loop
-consuming 100% of CPU. So clean up and exit.
-
-Signed-off-by: Holger Macht <hmacht@suse.de>
----
-
-diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
-index d2fc941..26038c2 100644
---- a/drivers/acpi/bay.c
-+++ b/drivers/acpi/bay.c
-@@ -299,16 +299,20 @@ static int bay_add(acpi_handle handle, int id)
- */
- pdev->dev.uevent_suppress = 0;
-
-- if (acpi_bay_add_fs(new_bay)) {
-- platform_device_unregister(new_bay->pdev);
-- goto bay_add_err;
-- }
--
- /* register for events on this device */
- status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
- bay_notify, new_bay);
- if (ACPI_FAILURE(status)) {
-- printk(KERN_ERR PREFIX "Error installing bay notify handler\n");
-+ printk(KERN_INFO PREFIX "Error installing bay notify handler\n");
-+ platform_device_unregister(new_bay->pdev);
-+ goto bay_add_err;
-+ }
-+
-+ if (acpi_bay_add_fs(new_bay)) {
-+ acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-+ bay_notify);
-+ platform_device_unregister(new_bay->pdev);
-+ goto bay_add_err;
- }
-
- /* if we are on a dock station, we should register for dock
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/01-disk-protect-for-2.6.25.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/01-disk-protect-for-2.6.25.patch
deleted file mode 100644
index 9738753..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/01-disk-protect-for-2.6.25.patch
+++ /dev/null
@@ -1,917 +0,0 @@
-diff -Naur a/block/blk-core.c b/block/blk-core.c
---- a/block/blk-core.c 2008-04-13 14:04:22.000000000 +0200
-+++ b/block/blk-core.c 2008-04-13 14:25:48.000000000 +0200
-@@ -320,6 +320,46 @@
- }
- EXPORT_SYMBOL(blk_unplug);
-
-+/*
-+ * Issue lower level unprotect function if no timers are pending.
-+ */
-+void blk_unfreeze_work(struct work_struct *work)
-+{
-+ struct request_queue *q = container_of(work, struct request_queue, unfreeze_work);
-+ int pending;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(q->queue_lock, flags);
-+ pending = timer_pending(&q->unfreeze_timer);
-+ spin_unlock_irqrestore(q->queue_lock, flags);
-+ if (!pending)
-+ q->issue_unprotect_fn(q);
-+}
-+
-+/*
-+ * Called when the queue freeze timeout expires...
-+ */
-+void blk_unfreeze_timeout(unsigned long data)
-+{
-+ struct request_queue *q = (struct request_queue *) data;
-+
-+ kblockd_schedule_work(&q->unfreeze_work);
-+}
-+
-+/*
-+ * The lower level driver parks and freezes the queue, and this block layer
-+ * function sets up the freeze timeout timer on return. If the queue is
-+ * already frozen then this is called to extend the timer...
-+ */
-+void blk_freeze_queue(struct request_queue *q, int seconds)
-+{
-+ /* Don't accept arbitrarily long freezes */
-+ if (seconds >= q->max_unfreeze)
-+ seconds = q->max_unfreeze;
-+ /* set/reset the timer */
-+ mod_timer(&q->unfreeze_timer, msecs_to_jiffies(seconds*1000) + jiffies);
-+}
-+
- /**
- * blk_start_queue - restart a previously stopped queue
- * @q: The &struct request_queue in question
-@@ -482,6 +522,7 @@
- }
-
- init_timer(&q->unplug_timer);
-+ init_timer(&q->unfreeze_timer);
-
- kobject_init(&q->kobj, &blk_queue_ktype);
-
-diff -Naur a/block/blk.h b/block/blk.h
---- a/block/blk.h 2008-04-13 14:04:22.000000000 +0200
-+++ b/block/blk.h 2008-04-13 14:25:48.000000000 +0200
-@@ -18,6 +18,9 @@
-
- void blk_unplug_work(struct work_struct *work);
- void blk_unplug_timeout(unsigned long data);
-+void blk_unfreeze_work(struct work_struct *work);
-+void blk_unfreeze_timeout(unsigned long data);
-+void blk_freeze_queue(struct request_queue *q, int seconds);
-
- struct io_context *current_io_context(gfp_t gfp_flags, int node);
-
-diff -Naur a/block/blk-settings.c b/block/blk-settings.c
---- a/block/blk-settings.c 2008-04-13 14:04:22.000000000 +0200
-+++ b/block/blk-settings.c 2008-04-13 14:25:48.000000000 +0200
-@@ -112,6 +112,16 @@
- q->unplug_timer.function = blk_unplug_timeout;
- q->unplug_timer.data = (unsigned long)q;
-
-+ q->max_unfreeze = 30;
-+
-+ INIT_WORK(&q->unfreeze_work, blk_unfreeze_work);
-+
-+ q->unfreeze_timer.function = blk_unfreeze_timeout;
-+ q->unfreeze_timer.data = (unsigned long)q;
-+
-+ /* Set protect_method to auto detection initially */
-+ q->protect_method = 2;
-+
- /*
- * by default assume old behaviour and bounce for any highmem page
- */
-@@ -119,6 +129,18 @@
- }
- EXPORT_SYMBOL(blk_queue_make_request);
-
-+void blk_queue_issue_protect_fn(struct request_queue *q, issue_protect_fn *ipf)
-+{
-+ q->issue_protect_fn = ipf;
-+}
-+EXPORT_SYMBOL(blk_queue_issue_protect_fn);
-+
-+void blk_queue_issue_unprotect_fn(struct request_queue *q, issue_unprotect_fn *iuf)
-+{
-+ q->issue_unprotect_fn = iuf;
-+}
-+EXPORT_SYMBOL(blk_queue_issue_unprotect_fn);
-+
- /**
- * blk_queue_bounce_limit - set bounce buffer limit for queue
- * @q: the request queue for the device
-diff -Naur a/block/blk-sysfs.c b/block/blk-sysfs.c
---- a/block/blk-sysfs.c 2008-04-13 14:04:22.000000000 +0200
-+++ b/block/blk-sysfs.c 2008-04-13 14:25:48.000000000 +0200
-@@ -270,6 +270,160 @@
- .release = blk_release_queue,
- };
-
-+/*
-+ * When reading the 'protect' attribute, we return seconds remaining
-+ * before unfreeze timeout expires
-+ */
-+static ssize_t queue_protect_show(struct request_queue *q, char *page)
-+{
-+ unsigned int seconds = 0;
-+
-+ spin_lock_irq(q->queue_lock);
-+ if (blk_queue_stopped(q) && timer_pending(&q->unfreeze_timer))
-+ /*
-+ * Adding 1 in order to guarantee nonzero value until timer
-+ * has actually expired.
-+ */
-+ seconds = jiffies_to_msecs(q->unfreeze_timer.expires
-+ - jiffies) / 1000 + 1;
-+ spin_unlock_irq(q->queue_lock);
-+ return queue_var_show(seconds, (page));
-+}
-+
-+/*
-+ * When writing the 'protect' attribute, input is the number of seconds
-+ * to freeze the queue for. We call a lower level helper function to
-+ * park the heads and freeze/block the queue, then we make a block layer
-+ * call to setup the thaw timeout. If input is 0, then we thaw the queue.
-+ */
-+static ssize_t queue_protect_store(struct request_queue *q,
-+ const char *page, size_t count)
-+{
-+ unsigned long freeze = 0;
-+
-+ queue_var_store(&freeze, page, count);
-+
-+ if (freeze>0) {
-+ /* Park and freeze */
-+ if (!blk_queue_stopped(q))
-+ q->issue_protect_fn(q);
-+ /* set / reset the thaw timer */
-+ spin_lock_irq(q->queue_lock);
-+ blk_freeze_queue(q, freeze);
-+ spin_unlock_irq(q->queue_lock);
-+ } else {
-+ spin_lock_irq(q->queue_lock);
-+ freeze = del_timer(&q->unfreeze_timer);
-+ spin_unlock_irq(q->queue_lock);
-+ if (freeze)
-+ q->issue_unprotect_fn(q);
-+ }
-+
-+ return count;
-+}
-+
-+static ssize_t
-+queue_str_show(char *page, char *str, int status)
-+{
-+ ssize_t len;
-+
-+ if (status & 1)
-+ len = sprintf(page, "[%s]", str);
-+ else
-+ len = sprintf(page, "%s", str);
-+ if (status & 2)
-+ len += sprintf(page+len, "\n");
-+ else
-+ len += sprintf(page+len, " ");
-+ return len;
-+}
-+
-+/*
-+ * Returns current protect_method.
-+ */
-+static ssize_t queue_protect_method_show(struct request_queue *q, char *page)
-+{
-+ int len = 0;
-+ int unload = q->protect_method;
-+
-+ len += queue_str_show(page+len, "auto", (unload & 2) >> 1);
-+ len += queue_str_show(page+len, "unload", unload & 1);
-+ len += queue_str_show(page+len, "standby", !unload ? 3 : 2);
-+ return len;
-+}
-+
-+/*
-+ * Stores the device protect method.
-+ */
-+static ssize_t queue_protect_method_store(struct request_queue *q,
-+ const char *page, size_t count)
-+{
-+ spin_lock_irq(q->queue_lock);
-+ if (!strcmp(page, "auto") || !strcmp(page, "auto\n"))
-+ q->protect_method = 2;
-+ else if (!strcmp(page, "unload") || !strcmp(page, "unload\n"))
-+ q->protect_method = 1;
-+ else if (!strcmp(page, "standby") || !strcmp(page, "standby\n"))
-+ q->protect_method = 0;
-+ else {
-+ spin_unlock_irq(q->queue_lock);
-+ return -EINVAL;
-+ }
-+ spin_unlock_irq(q->queue_lock);
-+ return count;
-+}
-+
-+static struct queue_sysfs_entry queue_protect_entry = {
-+ .attr = { .name = "protect", .mode = S_IRUGO | S_IWUSR },
-+ .show = queue_protect_show,
-+ .store = queue_protect_store,
-+};
-+static struct queue_sysfs_entry queue_protect_method_entry = {
-+ .attr = { .name = "protect_method", .mode = S_IRUGO | S_IWUSR },
-+ .show = queue_protect_method_show,
-+ .store = queue_protect_method_store,
-+};
-+
-+static int blk_protect_register(struct request_queue *q)
-+{
-+ int error = 0;
-+
-+ /* check that the lower level driver has a protect handler */
-+ if (!q->issue_protect_fn)
-+ return 0;
-+
-+ /* create the attributes */
-+ error = sysfs_create_file(&q->kobj, &queue_protect_entry.attr);
-+ if (error) {
-+ printk(KERN_ERR
-+ "blk_protect_register(): failed to create protect queue attribute!\n");
-+ return error;
-+ }
-+
-+ error = sysfs_create_file(&q->kobj, &queue_protect_method_entry.attr);
-+ if (error) {
-+ sysfs_remove_file(&q->kobj, &queue_protect_entry.attr);
-+ printk(KERN_ERR
-+ "blk_protect_register(): failed to create protect_method attribute!\n");
-+ return error;
-+ }
-+ kobject_get(&q->kobj);
-+
-+ return 0;
-+}
-+
-+static void blk_protect_unregister(struct request_queue *q)
-+{
-+ /* check that the lower level driver has a protect handler */
-+ if (!q->issue_protect_fn)
-+ return;
-+
-+ /* remove the attributes */
-+ sysfs_remove_file(&q->kobj, &queue_protect_method_entry.attr);
-+ sysfs_remove_file(&q->kobj, &queue_protect_entry.attr);
-+ kobject_put(&q->kobj);
-+}
-+
- int blk_register_queue(struct gendisk *disk)
- {
- int ret;
-@@ -287,13 +441,20 @@
- kobject_uevent(&q->kobj, KOBJ_ADD);
-
- ret = elv_register_queue(q);
-+ if (ret)
-+ goto err;
-+ ret = blk_protect_register(q);
- if (ret) {
-- kobject_uevent(&q->kobj, KOBJ_REMOVE);
-- kobject_del(&q->kobj);
-- return ret;
-+ elv_unregister_queue(q);
-+ goto err;
- }
-
- return 0;
-+
-+err:
-+ kobject_uevent(&q->kobj, KOBJ_REMOVE);
-+ kobject_del(&q->kobj);
-+ return ret;
- }
-
- void blk_unregister_queue(struct gendisk *disk)
-@@ -301,6 +462,7 @@
- struct request_queue *q = disk->queue;
-
- if (q && q->request_fn) {
-+ blk_protect_unregister(q);
- elv_unregister_queue(q);
-
- kobject_uevent(&q->kobj, KOBJ_REMOVE);
-diff -Naur a/Documentation/block/disk-protection.txt b/Documentation/block/disk-protection.txt
---- a/Documentation/block/disk-protection.txt 1970-01-01 01:00:00.000000000 +0100
-+++ b/Documentation/block/disk-protection.txt 2008-04-13 14:25:48.000000000 +0200
-@@ -0,0 +1,79 @@
-+Hard disk protection
-+====================
-+
-+
-+Intro
-+-----
-+ATA/ATAPI-7 specifies the IDLE IMMEDIATE command with UNLOAD FEATURE.
-+Issuing this command should cause the drive to switch to idle mode and
-+unload disk heads. This feature is being used in modern laptops in
-+conjunction with accelerometers and appropriate software to implement
-+a shock protection facility. The idea is to stop all I/O operations on
-+the internal hard drive and park its heads on the ramp when critical
-+situations are anticipated. The desire to have such a feature
-+available on GNU/Linux systems has been the original motivation to
-+implement a generic disk parking interface in the Linux kernel.
-+
-+
-+The interface
-+-------------
-+The interface works as follows: Writing an integer value to
-+/sys/block/*/queue/protect will park the respective drive and freeze
-+the block layer queue for the specified number of seconds. When the
-+timeout expires and no further disk park request has been issued in
-+the meantime, the queue is unfrozen and accumulated I/O operations are
-+performed.
-+
-+IMPORTANT NOTE:
-+Not all ATA drives implement IDLE IMMEDIATE with UNLOAD FEATURE and
-+quite a few of those that do so, don't report this capability as
-+described in the specs. When a disk park has been requested through
-+sysfs as described above, the kernel will try to determine if the
-+drive supports the UNLOAD FEATURE by default. The kernel will only
-+rely on the IDLE IMMEDIATE with UNLOAD FEATURE command if it is
-+convinced that this command is actually supported by the disk drive;
-+otherwise, it will fall back to STANDBY IMMEDIATE. Resuming from the
-+latter will take much longer and it is generally more likely to have a
-+negative impact on the drive's lifetime due to the inclease of spin
-+down and up cycles. If you want to use this interface in a shock
-+protection framework and you know that your drive does indeed support
-+the IDLE IMMEDIATE with UNLOAD FEATURE command despite not saying so,
-+you can force the kernel to issue that command by doing the following
-+on the command line:
-+# echo -n unload > /sys/block/sda/queue/protect_method
-+(replace sda by the drive identifier as appropriate).
-+
-+/sys/block/*/queue/protect_method accepts auto, unload and standby
-+respectively. Reading from protect_method shows the available options
-+surrounding the active one with brackets. When auto is active, this
-+will change to whatever the kernel sees fit after the next disk park
-+command has been issued.
-+
-+
-+References
-+----------
-+
-+There are several laptops from different brands featuring shock
-+protection capabilities. As manufacturers have refused to support open
-+source development of the required software components so far, Linux
-+support for shock protection varies considerably between different
-+hardware implementations. Ideally, this section should contain a list
-+of poiters at different projects aiming at an implementation of shock
-+protection on different systeems. Unfortunately, I only know of a
-+single project which, although still considered experimental, is fit
-+for use. Please feel free to add projects that have been the victims
-+of my ignorance.
-+
-+- http://www.thinkwiki.org/wiki/HDAPS
-+ See this page for information about Linux support of the hard disk
-+ active protection syystem as implemented in IBM/Lenovo Thinkpads.
-+
-+
-+CREDITS
-+-------
-+
-+The patch to implement the interface described in this file has
-+originally been published by Jon Escombe <lists-Xbpc2PeERmvQXOPxS62xeg@public.gmane.org>.
-+
-+
-+05 Dec 2006, Elias Oltmanns <eo-oA28OIkTjSVZXbeN9DUtxg@public.gmane.org>
-diff -Naur a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
---- a/drivers/ata/libata-scsi.c 2008-04-13 14:04:23.000000000 +0200
-+++ b/drivers/ata/libata-scsi.c 2008-04-13 14:26:04.000000000 +0200
-@@ -831,7 +831,7 @@
- * prevent SCSI midlayer from automatically deferring
- * requests.
- */
-- sdev->max_device_blocked = 1;
-+ sdev->max_device_blocked = 2;
- }
-
- /**
-@@ -905,6 +905,38 @@
- return 0;
- }
-
-+extern int scsi_protect_queue(struct request_queue *q, int unload);
-+extern int scsi_unprotect_queue(struct request_queue *q);
-+
-+static int ata_scsi_issue_protect_fn(struct request_queue *q)
-+{
-+ struct scsi_device *sdev = q->queuedata;
-+ struct ata_port *ap = ata_shost_to_port(sdev->host);
-+ struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
-+ int unload = q->protect_method;
-+ unsigned long flags;
-+
-+ if (!dev) {
-+ printk(KERN_DEBUG "ata_scsi_issue_protect_fn(): Couldn't find ATA device to be parked.\n");
-+ return -ENXIO;
-+ }
-+
-+ if (unload == 2) {
-+ unload = ata_id_has_unload(dev->id) ? 1 : 0;
-+ spin_lock_irqsave(q->queue_lock, flags);
-+ q->protect_method = unload;
-+ spin_unlock_irqrestore(q->queue_lock, flags);
-+ }
-+
-+ /* call scsi_protect_queue, requesting either unload or standby */
-+ return scsi_protect_queue(q, unload);
-+}
-+
-+static int ata_scsi_issue_unprotect_fn(struct request_queue *q)
-+{
-+ return scsi_unprotect_queue(q);
-+}
-+
- /**
- * ata_scsi_slave_config - Set SCSI device attributes
- * @sdev: SCSI device to examine
-@@ -927,6 +959,10 @@
-
- if (dev)
- rc = ata_scsi_dev_config(sdev, dev);
-+ blk_queue_issue_protect_fn(sdev->request_queue,
-+ ata_scsi_issue_protect_fn);
-+ blk_queue_issue_unprotect_fn(sdev->request_queue,
-+ ata_scsi_issue_unprotect_fn);
-
- return rc;
- }
-@@ -3206,7 +3242,7 @@
- * Set host_blocked to 1 to prevent SCSI midlayer from
- * automatically deferring requests.
- */
-- shost->max_host_blocked = 1;
-+ shost->max_host_blocked = 2;
-
- rc = scsi_add_host(ap->scsi_host, ap->host->dev);
- if (rc)
-diff -Naur a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
---- a/drivers/ide/ide-disk.c 2008-04-13 14:04:31.000000000 +0200
-+++ b/drivers/ide/ide-disk.c 2008-04-13 14:25:48.000000000 +0200
-@@ -612,6 +612,148 @@
- }
-
- /*
-+ * todo:
-+ * - we freeze the queue regardless of success and rely on the
-+ * ide_protect_queue function to thaw immediately if the command
-+ * failed (to be consistent with the libata handler)... should
-+ * we also inspect here?
-+ */
-+void ide_end_protect_rq(struct request *rq, int error)
-+{
-+ struct completion *waiting = rq->end_io_data;
-+
-+ rq->end_io_data = NULL;
-+ /* spin lock already accquired */
-+ if (!blk_queue_stopped(rq->q))
-+ blk_stop_queue(rq->q);
-+
-+ complete(waiting);
-+}
-+
-+int ide_unprotect_queue(struct request_queue *q)
-+{
-+ struct request rq;
-+ unsigned long flags;
-+ int pending, rc = 0;
-+ ide_drive_t *drive = q->queuedata;
-+ ide_task_t task;
-+
-+ if (!blk_queue_stopped(q))
-+ return -EIO;
-+
-+ /* Are there any pending jobs on the queue? */
-+ pending = ((q->rq.count[READ] > 0) || (q->rq.count[WRITE] > 0)) ? 1 : 0;
-+
-+ spin_lock_irqsave(q->queue_lock, flags);
-+ blk_start_queue(q);
-+ spin_unlock_irqrestore(q->queue_lock, flags);
-+
-+ /* The unload feature of the IDLE_IMMEDIATE command
-+ temporarily disables HD power management from spinning down
-+ the disk. Any other command will reenable HD pm, so, if
-+ there are no pending jobs on the queue, another
-+ CHECK_POWER_MODE1 command without the unload feature should do
-+ just fine. */
-+ if (!pending) {
-+ printk(KERN_DEBUG "ide_unprotect_queue(): No pending I/O, re-enabling power management..\n");
-+ memset(&task, 0, sizeof(task));
-+ task.tf.command = WIN_CHECKPOWERMODE1; /* CHECK_POWER_MODE1 */
-+ task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-+ task.data_phase = TASKFILE_NO_DATA;
-+ ide_init_drive_cmd(&rq);
-+ rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
-+ rq.special = &task;
-+ rc = ide_do_drive_cmd(drive, &rq, ide_head_wait);
-+ }
-+
-+ return rc;
-+}
-+
-+int ide_protect_queue(struct request_queue *q, int unload)
-+{
-+ ide_drive_t *drive = q->queuedata;
-+ struct request rq;
-+ ide_task_t task;
-+ int ret = 0;
-+ DECLARE_COMPLETION(wait);
-+
-+ memset(&rq, 0, sizeof(rq));
-+ memset(&task, 0, sizeof(task));
-+
-+ if (blk_queue_stopped(q))
-+ return -EIO;
-+
-+ task.data_phase = TASKFILE_NO_DATA;
-+ task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-+ if (unload) {
-+ task.tf.command = 0xe1;
-+ task.tf.feature = 0x44;
-+ task.tf.lbal = 0x4c;
-+ task.tf.lbam = 0x4e;
-+ task.tf.lbah = 0x55;
-+ } else
-+ task.tf.command = 0xe0;
-+
-+ /* Issue the park command & freeze */
-+ ide_init_drive_cmd(&rq);
-+
-+ rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
-+ rq.special = &task;
-+ rq.end_io_data = &wait;
-+ rq.end_io = ide_end_protect_rq;
-+
-+ ret = ide_do_drive_cmd(drive, &rq, ide_next);
-+ wait_for_completion(&wait);
-+
-+ if (ret) {
-+ printk(KERN_DEBUG "ide_protect_queue(): Warning: head NOT parked!..\n");
-+ ide_unprotect_queue(q);
-+ return ret;
-+ }
-+
-+ if (unload) {
-+ if (task.tf.lbal == 0xc4)
-+ printk(KERN_DEBUG "ide_protect_queue(): head parked..\n");
-+ else {
-+ /* error parking the head */
-+ printk(KERN_DEBUG "ide_protect_queue(): head NOT parked!..\n");
-+ ret = -EIO;
-+ ide_unprotect_queue(q);
-+ }
-+ } else
-+ printk(KERN_DEBUG "ide_protect_queue(): head park not requested, used standby!..\n");
-+
-+ return ret;
-+}
-+
-+int idedisk_issue_protect_fn(struct request_queue *q)
-+{
-+ ide_drive_t *drive = q->queuedata;
-+ int unload = q->protect_method;
-+ unsigned long flags;
-+
-+ /*
-+ * Check capability of the device -
-+ * - if "idle immediate with unload" is supported we use that, else
-+ * we use "standby immediate" and live with spinning down the drive..
-+ * (Word 84, bit 13 of IDENTIFY DEVICE data)
-+ */
-+ if (unload == 2) {
-+ unload = drive->id->cfsse & (1 << 13) ? 1 : 0;
-+ spin_lock_irqsave(q->queue_lock, flags);
-+ q->protect_method = unload;
-+ spin_unlock_irqrestore(q->queue_lock, flags);
-+ }
-+
-+ return ide_protect_queue(q, unload);
-+}
-+
-+int idedisk_issue_unprotect_fn(struct request_queue *q)
-+{
-+ return ide_unprotect_queue(q);
-+}
-+
-+/*
- * This is tightly woven into the driver->do_special can not touch.
- * DON'T do it again until a total personality rewrite is committed.
- */
-@@ -877,6 +1019,9 @@
- drive->wcache = 1;
-
- write_cache(drive, 1);
-+
-+ blk_queue_issue_protect_fn(drive->queue, idedisk_issue_protect_fn);
-+ blk_queue_issue_unprotect_fn(drive->queue, idedisk_issue_unprotect_fn);
- }
-
- static void ide_cacheflush_p(ide_drive_t *drive)
-diff -Naur a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
---- a/drivers/ide/ide-io.c 2008-04-13 14:04:31.000000000 +0200
-+++ b/drivers/ide/ide-io.c 2008-04-13 14:25:48.000000000 +0200
-@@ -1158,6 +1158,17 @@
- }
-
- /*
-+ * Don't accept a request when the queue is stopped (unless we
-+ * are resuming from suspend). Prevents existing queue entries
-+ * being processed after queue is stopped by the hard disk
-+ * protection mechanism...
-+ */
-+ if (test_bit(QUEUE_FLAG_STOPPED, &drive->queue->queue_flags) && !blk_pm_resume_request(rq)) {
-+ hwgroup->busy = 0;
-+ break;
-+ }
-+
-+ /*
- * Sanity: don't accept a request that isn't a PM request
- * if we are currently power managed. This is very important as
- * blk_stop_queue() doesn't prevent the elv_next_request()
-@@ -1651,6 +1662,9 @@
- where = ELEVATOR_INSERT_FRONT;
- rq->cmd_flags |= REQ_PREEMPT;
- }
-+ if (action == ide_next)
-+ where = ELEVATOR_INSERT_FRONT;
-+
- __elv_add_request(drive->queue, rq, where, 0);
- ide_do_request(hwgroup, IDE_NO_IRQ);
- spin_unlock_irqrestore(&ide_lock, flags);
-diff -Naur a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
---- a/drivers/scsi/scsi_lib.c 2008-04-13 14:04:50.000000000 +0200
-+++ b/drivers/scsi/scsi_lib.c 2008-04-13 14:25:48.000000000 +0200
-@@ -2248,7 +2248,13 @@
- int
- scsi_device_quiesce(struct scsi_device *sdev)
- {
-+ int i;
- int err = scsi_device_set_state(sdev, SDEV_QUIESCE);
-+ for (i = 0; err && (sdev->sdev_state == SDEV_BLOCK) && (i < 100);
-+ i++) {
-+ msleep_interruptible(200);
-+ err = scsi_device_set_state(sdev, SDEV_QUIESCE);
-+ }
- if (err)
- return err;
-
-@@ -2496,3 +2502,168 @@
- kunmap_atomic(virt, KM_BIO_SRC_IRQ);
- }
- EXPORT_SYMBOL(scsi_kunmap_atomic_sg);
-+
-+/*
-+ * Structure required for synchronous io completion after queue freezing
-+ */
-+struct scsi_protect_io_context_sync {
-+ struct scsi_device *sdev;
-+ int result;
-+ char *sense;
-+ struct completion *waiting;
-+};
-+
-+/*
-+ * scsi_protect_wait_done()
-+ * Command completion handler for scsi_protect_queue().
-+ *
-+ * Unable to call scsi_internal_device_block() as
-+ * scsi_end_request() already has the spinlock. So,
-+ * we put the necessary functionality inline.
-+ *
-+ * todo:
-+ * - we block the queue regardless of success and rely on the
-+ * scsi_protect_queue function to unblock if the command
-+ * failed... should we also inspect here?
-+ */
-+static void scsi_protect_wait_done(void *data, char *sense, int result, int resid)
-+{
-+ struct scsi_protect_io_context_sync *siocs = data;
-+ struct completion *waiting = siocs->waiting;
-+ struct request_queue *q = siocs->sdev->request_queue;
-+
-+ siocs->waiting = NULL;
-+ siocs->result = result;
-+ memcpy(siocs->sense, sense, SCSI_SENSE_BUFFERSIZE);
-+
-+ if (!scsi_device_set_state(siocs->sdev, SDEV_BLOCK))
-+ blk_stop_queue(q);
-+
-+ complete(waiting);
-+}
-+
-+/*
-+ * scsi_unprotect_queue()
-+ * - release the queue that was previously blocked
-+ */
-+int scsi_unprotect_queue(struct request_queue *q)
-+{
-+ struct scsi_device *sdev = q->queuedata;
-+ int rc = 0, pending = 0;
-+ u8 scsi_cmd[MAX_COMMAND_SIZE];
-+ struct scsi_sense_hdr sshdr;
-+
-+ if (sdev->sdev_state != SDEV_BLOCK)
-+ return -ENXIO;
-+
-+ /* Are there any pending jobs on the queue? */
-+ pending = ((q->rq.count[READ] > 0) || (q->rq.count[WRITE] > 0)) ? 1 : 0;
-+
-+ rc = scsi_internal_device_unblock(sdev);
-+ if (rc)
-+ return rc;
-+
-+ if (!pending) {
-+ printk(KERN_DEBUG "scsi_unprotect_queue(): No pending I/O, re-enabling power management..\n");
-+
-+ memset(scsi_cmd, 0, sizeof(scsi_cmd));
-+ scsi_cmd[0] = ATA_16;
-+ scsi_cmd[1] = (3 << 1); /* Non-data */
-+ /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
-+ scsi_cmd[14] = 0xe5; /* CHECK_POWER_MODE1 */
-+
-+ /* Good values for timeout and retries? Values below
-+ from scsi_ioctl_send_command() for default case... */
-+ if (scsi_execute_req(sdev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr,
-+ (10*HZ), 5))
-+ rc = -EIO;
-+ }
-+ return rc;
-+}
-+EXPORT_SYMBOL_GPL(scsi_unprotect_queue);
-+
-+/*
-+ * scsi_protect_queue()
-+ * - build and issue the park/standby command..
-+ * - queue is blocked during command completion handler
-+ */
-+int scsi_protect_queue(struct request_queue *q, int unload)
-+{
-+ struct scsi_protect_io_context_sync siocs;
-+ struct scsi_device *sdev = q->queuedata;
-+ int rc = 0;
-+ u8 args[7];
-+ u8 scsi_cmd[MAX_COMMAND_SIZE];
-+ unsigned char sense[SCSI_SENSE_BUFFERSIZE];
-+ unsigned char *desc;
-+ DECLARE_COMPLETION_ONSTACK(wait);
-+
-+ if (sdev->sdev_state != SDEV_RUNNING)
-+ return -ENXIO;
-+
-+ memset(args, 0, sizeof(args));
-+ memset(sense, 0, sizeof(sense));
-+
-+ if (unload) {
-+ args[0] = 0xe1;
-+ args[1] = 0x44;
-+ args[3] = 0x4c;
-+ args[4] = 0x4e;
-+ args[5] = 0x55;
-+ } else
-+ args[0] = 0xe0;
-+
-+ memset(scsi_cmd, 0, sizeof(scsi_cmd));
-+ scsi_cmd[0] = ATA_16;
-+ scsi_cmd[1] = (3 << 1); /* Non-data */
-+ scsi_cmd[2] = 0x20; /* no off.line, or data xfer, request cc */
-+ scsi_cmd[4] = args[1];
-+ scsi_cmd[6] = args[2];
-+ scsi_cmd[8] = args[3];
-+ scsi_cmd[10] = args[4];
-+ scsi_cmd[12] = args[5];
-+ scsi_cmd[14] = args[0];
-+ siocs.sdev = sdev;
-+ siocs.sense = sense;
-+ siocs.waiting = &wait;
-+
-+ rc = scsi_execute_async(sdev, scsi_cmd, COMMAND_SIZE(scsi_cmd[0]),
-+ DMA_NONE, NULL, 0, 0, (10*HZ), 5,
-+ &siocs, &scsi_protect_wait_done, GFP_NOWAIT);
-+ if (rc)
-+ goto out;
-+ wait_for_completion(&wait);
-+
-+ if (siocs.result != ((DRIVER_SENSE << 24) + SAM_STAT_CHECK_CONDITION)) {
-+ printk(KERN_DEBUG "scsi_protect_queue(): head NOT parked!..\n");
-+ scsi_unprotect_queue(q); /* just in case we still managed to block */
-+ rc = -EIO;
-+ goto out;
-+ }
-+
-+ desc = sense + 8;
-+
-+ /* Retrieve data from check condition */
-+ args[1] = desc[3];
-+ args[2] = desc[5];
-+ args[3] = desc[7];
-+ args[4] = desc[9];
-+ args[5] = desc[11];
-+ args[0] = desc[13];
-+
-+ if (unload) {
-+ if (args[3] == 0xc4)
-+ printk(KERN_DEBUG "scsi_protect_queue(): head parked..\n");
-+ else {
-+ /* error parking the head */
-+ printk(KERN_DEBUG "scsi_protect_queue(): head NOT parked!..\n");
-+ rc = -EIO;
-+ scsi_unprotect_queue(q);
-+ }
-+ } else
-+ printk(KERN_DEBUG "scsi_protect_queue(): head park not requested, used standby!..\n");
-+
-+out:
-+ return rc;
-+}
-+EXPORT_SYMBOL_GPL(scsi_protect_queue);
-diff -Naur a/include/linux/ata.h b/include/linux/ata.h
---- a/include/linux/ata.h 2008-04-13 14:04:53.000000000 +0200
-+++ b/include/linux/ata.h 2008-04-13 14:25:48.000000000 +0200
-@@ -459,6 +459,18 @@
-
- #define ata_id_cdb_intr(id) (((id)[0] & 0x60) == 0x20)
-
-+static inline int ata_id_has_unload(const u16 *id)
-+{
-+ /* ATA-7 specifies two places to indicate unload feature support.
-+ * Since I don't really understand the difference, I'll just check
-+ * both and only return zero if none of them indicates otherwise. */
-+ if ((id[84] & 0xC000) == 0x4000 && id[84] & (1 << 13))
-+ return id[84] & (1 << 13);
-+ if ((id[87] & 0xC000) == 0x4000)
-+ return id[87] & (1 << 13);
-+ return 0;
-+}
-+
- static inline bool ata_id_has_hipm(const u16 *id)
- {
- u16 val = id[76];
-diff -Naur a/include/linux/blkdev.h b/include/linux/blkdev.h
---- a/include/linux/blkdev.h 2008-04-13 14:04:53.000000000 +0200
-+++ b/include/linux/blkdev.h 2008-04-13 14:25:48.000000000 +0200
-@@ -260,6 +260,8 @@
- typedef void (prepare_flush_fn) (struct request_queue *, struct request *);
- typedef void (softirq_done_fn)(struct request *);
- typedef int (dma_drain_needed_fn)(struct request *);
-+typedef int (issue_protect_fn) (struct request_queue *);
-+typedef int (issue_unprotect_fn) (struct request_queue *);
-
- enum blk_queue_state {
- Queue_down,
-@@ -297,6 +299,8 @@
- prepare_flush_fn *prepare_flush_fn;
- softirq_done_fn *softirq_done_fn;
- dma_drain_needed_fn *dma_drain_needed;
-+ issue_protect_fn *issue_protect_fn;
-+ issue_unprotect_fn *issue_unprotect_fn;
-
- /*
- * Dispatch queue sorting
-@@ -312,6 +316,14 @@
- unsigned long unplug_delay; /* After this many jiffies */
- struct work_struct unplug_work;
-
-+ /*
-+ * Auto-unfreeze state
-+ */
-+ struct timer_list unfreeze_timer;
-+ int max_unfreeze; /* At most this many seconds */
-+ struct work_struct unfreeze_work;
-+ int protect_method;
-+
- struct backing_dev_info backing_dev_info;
-
- /*
-@@ -718,6 +730,8 @@
- extern unsigned blk_ordered_cur_seq(struct request_queue *);
- extern unsigned blk_ordered_req_seq(struct request *);
- extern void blk_ordered_complete_seq(struct request_queue *, unsigned, int);
-+extern void blk_queue_issue_protect_fn(struct request_queue *, issue_protect_fn *);
-+extern void blk_queue_issue_unprotect_fn(struct request_queue *, issue_unprotect_fn *);
-
- extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *);
- extern void blk_dump_rq_flags(struct request *, char *);
-diff -Naur a/include/linux/ide.h b/include/linux/ide.h
---- a/include/linux/ide.h 2008-04-13 14:04:53.000000000 +0200
-+++ b/include/linux/ide.h 2008-04-13 14:25:48.000000000 +0200
-@@ -837,6 +837,7 @@
- */
- typedef enum {
- ide_wait, /* insert rq at end of list, and wait for it */
-+ ide_next, /* insert rq immediately after current request */
- ide_preempt, /* insert rq in front of current request */
- ide_head_wait, /* insert rq in front of current request and wait for it */
- ide_end /* insert rq at end of list, but don't wait for it */
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/02-ipw2200-inject-for-2.6.25.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/02-ipw2200-inject-for-2.6.25.patch
deleted file mode 100644
index ffb49a9..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/02-ipw2200-inject-for-2.6.25.patch
+++ /dev/null
@@ -1,77 +0,0 @@
---- a/drivers/net/wireless/ipw2200.c 2007-10-07 12:41:29.000000000 +0200
-+++ b/drivers/net/wireless/ipw2200.c 2007-10-07 12:50:43.000000000 +0200
-@@ -1860,6 +1860,66 @@
- static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
- show_net_stats, store_net_stats);
-
-+static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, int pri);
-+
-+/* SYSFS INJECT */
-+static ssize_t store_inject(struct device *d,
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
-+ struct device_attribute *attr,
-+#endif
-+ const char *buf, size_t count)
-+{
-+ struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
-+ struct ieee80211_device *ieee = priv->ieee;
-+ struct ieee80211_txb * txb;
-+ struct sk_buff *skb_frag;
-+ unsigned char * newbuf;
-+ unsigned long flags;
-+
-+ // should test (ieee->is_queue_full)
-+
-+ // Fw only accepts data, so avoid accidental fw errors.
-+ if ( (buf[0]&0x0c) != '\x08') {
-+ //printk("ipw2200: inject: discarding non-data frame (type=%02X)\n",(int)(unsigned char)buf[0]);
-+ return count;
-+ }
-+
-+ if (count>1500) {
-+ count=1500;
-+ printk("ipw2200: inject: cutting down frame to 1500 bytes\n");
-+ }
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+
-+ // Create a txb with one skb
-+ txb = kmalloc(sizeof(struct ieee80211_txb) + sizeof(u8 *), GFP_ATOMIC);
-+ if (!txb)
-+ goto nosepuede;
-+ txb->nr_frags=1;
-+ txb->frag_size = ieee->tx_headroom;
-+ txb->fragments[0]=__dev_alloc_skb(count + ieee->tx_headroom, GFP_ATOMIC);
-+ if (!txb->fragments[0]) {
-+ kfree(txb);
-+ goto nosepuede;
-+ }
-+ skb_reserve(txb->fragments[0], ieee->tx_headroom);
-+ txb->encrypted=0;
-+ txb->payload_size=count;
-+ skb_frag = txb->fragments[0];
-+ newbuf=skb_put(skb_frag, count);
-+
-+ // copy data into txb->skb and send it
-+ memcpy(newbuf, buf, count);
-+
-+ ipw_tx_skb(priv, txb, 0);
-+
-+nosepuede:
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+ return count;
-+}
-+
-+static DEVICE_ATTR(inject, S_IWUSR, NULL, store_inject);
-+
- static ssize_t show_channels(struct device *d,
- struct device_attribute *attr,
- char *buf)
-@@ -11498,6 +11558,7 @@
- #ifdef CONFIG_IPW2200_PROMISCUOUS
- &dev_attr_rtap_iface.attr,
- &dev_attr_rtap_filter.attr,
-+ &dev_attr_inject.attr,
- #endif
- NULL
- };
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/03-libata-acpi_hotplug_fixups-for-2.6.25.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/03-libata-acpi_hotplug_fixups-for-2.6.25.patch
deleted file mode 100644
index 8cd7b7f..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/03-libata-acpi_hotplug_fixups-for-2.6.25.patch
+++ /dev/null
@@ -1,215 +0,0 @@
-diff -Naur a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
---- a/drivers/ata/libata-acpi.c 2008-05-15 17:00:12.000000000 +0200
-+++ b/drivers/ata/libata-acpi.c 2008-06-03 20:53:52.000000000 +0200
-@@ -118,19 +118,82 @@
- ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
- }
-
-+static void ata_acpi_eject_device(acpi_handle handle)
-+{
-+ struct acpi_object_list arg_list;
-+ union acpi_object arg;
-+
-+ arg_list.count = 1;
-+ arg_list.pointer = &arg;
-+ arg.type = ACPI_TYPE_INTEGER;
-+ arg.integer.value = 1;
-+
-+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0",
-+ &arg_list, NULL)))
-+ printk(KERN_ERR "Failed to evaluate _EJ0!\n");
-+}
-+
-+/* @ap and @dev are the same as ata_acpi_handle_hotplug() */
-+static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
-+{
-+ if (dev)
-+ dev->flags |= ATA_DFLAG_DETACH;
-+ else {
-+ struct ata_link *tlink;
-+ struct ata_device *tdev;
-+
-+ ata_port_for_each_link(tlink, ap)
-+ ata_link_for_each_dev(tdev, tlink)
-+ tdev->flags |= ATA_DFLAG_DETACH;
-+ }
-+
-+ ata_port_schedule_eh(ap);
-+}
-+
-+/**
-+ * ata_acpi_handle_hotplug - ACPI event handler backend
-+ * @ap: ATA port ACPI event occurred
-+ * @dev: ATA device ACPI event occurred (can be NULL)
-+ * @event: ACPI event which occurred
-+ * @is_dock_event: boolean indicating whether the event was a dock one
-+ *
-+ * All ACPI bay / device realted events end up in this function. If
-+ * the event is port-wide @dev is NULL. If the event is specific to a
-+ * device, @dev points to it.
-+ *
-+ * Hotplug (as opposed to unplug) notification is always handled as
-+ * port-wide while unplug only kills the target device on device-wide
-+ * event.
-+ *
-+ * LOCKING:
-+ * ACPI notify handler context. May sleep.
-+ */
- static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
-- u32 event)
-+ u32 event, int is_dock_event)
- {
- char event_string[12];
- char *envp[] = { event_string, NULL };
-- struct ata_eh_info *ehi;
-+ struct ata_eh_info *ehi = &ap->link.eh_info;
- struct kobject *kobj = NULL;
- int wait = 0;
- unsigned long flags;
-+ acpi_handle handle, tmphandle;
-+ unsigned long sta;
-+ acpi_status status;
-+
-+ if (dev) {
-+ if (dev->sdev)
-+ kobj = &dev->sdev->sdev_gendev.kobj;
-+ handle = dev->acpi_handle;
-+ } else {
-+ kobj = &ap->dev->kobj;
-+ handle = ap->acpi_handle;
-+ }
-
-- if (!ap)
-- ap = dev->link->ap;
-- ehi = &ap->link.eh_info;
-+ status = acpi_get_handle(handle, "_EJ0", &tmphandle);
-+ if (ACPI_FAILURE(status))
-+ /* This device does not support hotplug */
-+ return;
-
- spin_lock_irqsave(ap->lock, flags);
-
-@@ -138,57 +201,80 @@
- case ACPI_NOTIFY_BUS_CHECK:
- case ACPI_NOTIFY_DEVICE_CHECK:
- ata_ehi_push_desc(ehi, "ACPI event");
-- ata_ehi_hotplugged(ehi);
-- ata_port_freeze(ap);
-- break;
-
-+ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-+ if (ACPI_FAILURE(status)) {
-+ ata_port_printk(ap, KERN_ERR,
-+ "acpi: failed to determine bay status (0x%x)\n",
-+ status);
-+ break;
-+ }
-+
-+ if (sta) {
-+ ata_ehi_hotplugged(ehi);
-+ ata_port_freeze(ap);
-+ } else {
-+ /* The device has gone - unplug it */
-+ ata_acpi_detach_device(ap, dev);
-+ wait = 1;
-+ }
-+ break;
- case ACPI_NOTIFY_EJECT_REQUEST:
- ata_ehi_push_desc(ehi, "ACPI event");
-- if (dev)
-- dev->flags |= ATA_DFLAG_DETACH;
-- else {
-- struct ata_link *tlink;
-- struct ata_device *tdev;
--
-- ata_port_for_each_link(tlink, ap)
-- ata_link_for_each_dev(tdev, tlink)
-- tdev->flags |= ATA_DFLAG_DETACH;
-- }
-
-- ata_port_schedule_eh(ap);
-+ if (!is_dock_event)
-+ break;
-+
-+ /* undock event - immediate unplug */
-+ ata_acpi_detach_device(ap, dev);
- wait = 1;
- break;
- }
-
-- if (dev) {
-- if (dev->sdev)
-- kobj = &dev->sdev->sdev_gendev.kobj;
-- } else
-- kobj = &ap->dev->kobj;
-+ /* make sure kobj doesn't go away while ap->lock is released */
-+ kobject_get(kobj);
-+
-+ spin_unlock_irqrestore(ap->lock, flags);
-+
-+ if (wait) {
-+ ata_port_wait_eh(ap);
-+ ata_acpi_eject_device(handle);
-+ }
-
-- if (kobj) {
-+ if (kobj && !is_dock_event) {
- sprintf(event_string, "BAY_EVENT=%d", event);
- kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
- }
-
-- spin_unlock_irqrestore(ap->lock, flags);
-+ kobject_put(kobj);
-+}
-
-- if (wait)
-- ata_port_wait_eh(ap);
-+static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
-+{
-+ struct ata_device *dev = data;
-+
-+ ata_acpi_handle_hotplug(dev->link->ap, dev, event, 1);
-+}
-+
-+static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
-+{
-+ struct ata_port *ap = data;
-+
-+ ata_acpi_handle_hotplug(ap, NULL, event, 1);
- }
-
- static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
- {
- struct ata_device *dev = data;
-
-- ata_acpi_handle_hotplug(NULL, dev, event);
-+ ata_acpi_handle_hotplug(dev->link->ap, dev, event, 0);
- }
-
- static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data)
- {
- struct ata_port *ap = data;
-
-- ata_acpi_handle_hotplug(ap, NULL, event);
-+ ata_acpi_handle_hotplug(ap, NULL, event, 0);
- }
-
- /**
-@@ -230,7 +316,7 @@
- #if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
- /* we might be on a docking station */
- register_hotplug_dock_device(ap->acpi_handle,
-- ata_acpi_ap_notify, ap);
-+ ata_acpi_ap_notify_dock, ap);
- #endif
- }
-
-@@ -244,7 +330,7 @@
- #if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
- /* we might be on a docking station */
- register_hotplug_dock_device(dev->acpi_handle,
-- ata_acpi_dev_notify, dev);
-+ ata_acpi_dev_notify_dock, dev);
- #endif
- }
- }
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/04-linux-phc-0.3.1-for-2.6.25.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/04-linux-phc-0.3.1-for-2.6.25.patch
deleted file mode 100644
index f40f581..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/04-linux-phc-0.3.1-for-2.6.25.patch
+++ /dev/null
@@ -1,526 +0,0 @@
-diff --new-file -a --unified=5 --recursive linux-2.6.24-rc1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.24-rc1_phc/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
---- linux-2.6.23-rc3/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-08-13 06:25:24.000000000 +0200
-+++ linux-source-2.6.23-rc3/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-08-14 15:33:30.000000000 +0200
-@@ -23,10 +23,15 @@
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-+/* This file has been patched with Linux PHC: https://www.dedigentoo.org/trac/linux-phc
-+ * Patch version: linux-phc-0.3.1-kernel-vanilla-2.6.23.patch
-+ */
-+
-+
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/smp.h>
- #include <linux/sched.h>
-@@ -59,12 +59,18 @@
- #define INTEL_MSR_RANGE (0xffff)
- #define CPUID_6_ECX_APERFMPERF_CAPABILITY (0x1)
-
-+#define INTEL_MSR_VID_MASK (0x00ff)
-+#define INTEL_MSR_FID_MASK (0xff00)
-+#define INTEL_MSR_FID_SHIFT (0x8)
-+#define PHC_VERSION_STRING "0.3.1:1"
-+
- struct acpi_cpufreq_data {
- struct acpi_processor_performance *acpi_data;
- struct cpufreq_frequency_table *freq_table;
- unsigned int max_freq;
- unsigned int resume;
- unsigned int cpu_feature;
-+ acpi_integer *original_controls;
- };
-
- static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
-@@ -102,17 +113,19 @@
- }
-
- static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
- {
- int i;
-+ u32 fid;
- struct acpi_processor_performance *perf;
-
-- msr &= INTEL_MSR_RANGE;
-+ fid = msr & INTEL_MSR_FID_MASK;
- perf = data->acpi_data;
-
- for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-- if (msr == perf->states[data->freq_table[i].index].status)
-+ if (fid == (perf->states[data->freq_table[i].index].status &
-+ INTEL_MSR_FID_MASK))
- return data->freq_table[i].frequency;
- }
- return data->freq_table[0].frequency;
- }
-
-@@ -729,10 +742,12 @@
- if (data) {
- cpufreq_frequency_table_put_attr(policy->cpu);
- per_cpu(drv_data, policy->cpu) = NULL;
- acpi_processor_unregister_performance(data->acpi_data,
- policy->cpu);
-+ if (data->original_controls)
-+ kfree(data->original_controls);
- kfree(data);
- }
-
- return 0;
- }
-@@ -746,12 +761,452 @@
- data->resume = 1;
-
- return 0;
- }
-
-+
-+
-+
-+/* sysfs interface to change operating points voltages */
-+
-+static unsigned int extract_fid_from_control(unsigned int control)
-+{
-+ return ((control & INTEL_MSR_FID_MASK) >> INTEL_MSR_FID_SHIFT);
-+}
-+
-+static unsigned int extract_vid_from_control(unsigned int control)
-+{
-+ return (control & INTEL_MSR_VID_MASK);
-+}
-+
-+static ssize_t check_origial_table (struct acpi_cpufreq_data *data)
-+{
-+ struct acpi_processor_performance *acpi_data;
-+ struct cpufreq_frequency_table *freq_table;
-+ unsigned int state_index;
-+
-+ acpi_data = data->acpi_data;
-+ freq_table = data->freq_table;
-+
-+ if (data->original_controls == NULL) {
-+ // Backup original control values
-+ data->original_controls = kcalloc(acpi_data->state_count,
-+ sizeof(acpi_integer), GFP_KERNEL);
-+ if (data->original_controls == NULL) {
-+ printk("failed to allocate memory for original control values\n");
-+ return -ENOMEM;
-+ }
-+ for (state_index = 0; state_index < acpi_data->state_count; state_index++) {
-+ data->original_controls[state_index] = acpi_data->states[state_index].control;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static ssize_t show_freq_attr_vids(struct cpufreq_policy *policy, char *buf)
-+{
-+ struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
-+ struct acpi_processor_performance *acpi_data;
-+ struct cpufreq_frequency_table *freq_table;
-+ unsigned int i;
-+ unsigned int vid;
-+ ssize_t count = 0;
-+
-+ if (unlikely(data == NULL ||
-+ data->acpi_data == NULL ||
-+ data->freq_table == NULL ||
-+ data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
-+ return -ENODEV;
-+ }
-+
-+ acpi_data = data->acpi_data;
-+ freq_table = data->freq_table;
-+
-+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-+ vid = extract_vid_from_control(acpi_data->states[freq_table[i].index].control);
-+ count += sprintf(&buf[count], "%u ", vid);
-+ }
-+ count += sprintf(&buf[count], "\n");
-+
-+ return count;
-+}
-+
-+static ssize_t show_freq_attr_default_vids(struct cpufreq_policy *policy, char *buf)
-+{
-+ struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
-+ struct cpufreq_frequency_table *freq_table;
-+ unsigned int i;
-+ unsigned int vid;
-+ ssize_t count = 0;
-+ ssize_t retval;
-+
-+ if (unlikely(data == NULL ||
-+ data->acpi_data == NULL ||
-+ data->freq_table == NULL ||
-+ data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
-+ return -ENODEV;
-+ }
-+
-+ retval = check_origial_table(data);
-+ if (0 != retval)
-+ return retval;
-+
-+ freq_table = data->freq_table;
-+
-+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-+ vid = extract_vid_from_control(data->original_controls[freq_table[i].index]);
-+ count += sprintf(&buf[count], "%u ", vid);
-+ }
-+ count += sprintf(&buf[count], "\n");
-+
-+ return count;
-+}
-+
-+static ssize_t show_freq_attr_fids(struct cpufreq_policy *policy, char *buf)
-+{
-+ struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
-+ struct acpi_processor_performance *acpi_data;
-+ struct cpufreq_frequency_table *freq_table;
-+ unsigned int i;
-+ unsigned int fid;
-+ ssize_t count = 0;
-+
-+ if (unlikely(data == NULL ||
-+ data->acpi_data == NULL ||
-+ data->freq_table == NULL ||
-+ data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
-+ return -ENODEV;
-+ }
-+
-+ acpi_data = data->acpi_data;
-+ freq_table = data->freq_table;
-+
-+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-+ fid = extract_fid_from_control(acpi_data->states[freq_table[i].index].control);
-+ count += sprintf(&buf[count], "%u ", fid);
-+ }
-+ count += sprintf(&buf[count], "\n");
-+
-+ return count;
-+}
-+
-+static ssize_t show_freq_attr_controls(struct cpufreq_policy *policy, char *buf)
-+{
-+ struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
-+ struct acpi_processor_performance *acpi_data;
-+ struct cpufreq_frequency_table *freq_table;
-+ unsigned int i;
-+ unsigned int fid;
-+ unsigned int vid;
-+ ssize_t count = 0;
-+
-+ if (unlikely(data == NULL ||
-+ data->acpi_data == NULL ||
-+ data->freq_table == NULL ||
-+ data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
-+ return -ENODEV;
-+ }
-+
-+ acpi_data = data->acpi_data;
-+ freq_table = data->freq_table;
-+
-+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-+ fid = extract_fid_from_control(acpi_data->states[freq_table[i].index].control);
-+ vid = extract_vid_from_control(acpi_data->states[freq_table[i].index].control);
-+ count += sprintf(&buf[count], "%u:%u ", fid, vid);
-+ }
-+ count += sprintf(&buf[count], "\n");
-+
-+ return count;
-+}
-+
-+static ssize_t show_freq_attr_default_controls(struct cpufreq_policy *policy, char *buf)
-+{
-+ struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
-+ struct cpufreq_frequency_table *freq_table;
-+ unsigned int i;
-+ unsigned int fid;
-+ unsigned int vid;
-+ ssize_t count = 0;
-+ ssize_t retval;
-+
-+ if (unlikely(data == NULL ||
-+ data->acpi_data == NULL ||
-+ data->freq_table == NULL ||
-+ data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
-+ return -ENODEV;
-+ }
-+
-+ retval = check_origial_table(data);
-+ if (0 != retval)
-+ return retval;
-+
-+ freq_table = data->freq_table;
-+
-+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-+ fid = extract_fid_from_control(data->original_controls[freq_table[i].index]);
-+ vid = extract_vid_from_control(data->original_controls[freq_table[i].index]);
-+ count += sprintf(&buf[count], "%u:%u ", fid, vid);
-+ }
-+ count += sprintf(&buf[count], "\n");
-+
-+ return count;
-+}
-+
-+
-+static ssize_t store_freq_attr_vids(struct cpufreq_policy *policy, const char *buf, size_t count)
-+{
-+ struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
-+ struct acpi_processor_performance *acpi_data;
-+ struct cpufreq_frequency_table *freq_table;
-+ unsigned int freq_index;
-+ unsigned int state_index;
-+ unsigned int new_vid;
-+ unsigned int original_vid;
-+ unsigned int new_control;
-+ unsigned int original_control;
-+ const char *curr_buf = buf;
-+ char *next_buf;
-+ ssize_t retval;
-+
-+ if (unlikely(data == NULL ||
-+ data->acpi_data == NULL ||
-+ data->freq_table == NULL ||
-+ data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
-+ return -ENODEV;
-+ }
-+
-+ retval = check_origial_table(data);
-+ if (0 != retval)
-+ return retval;
-+
-+ acpi_data = data->acpi_data;
-+ freq_table = data->freq_table;
-+
-+ for (freq_index = 0; freq_table[freq_index].frequency != CPUFREQ_TABLE_END; freq_index++) {
-+ new_vid = simple_strtoul(curr_buf, &next_buf, 10);
-+ if (next_buf == curr_buf) {
-+ if ((curr_buf - buf == count - 1) && (*curr_buf == '\n')) {
-+ curr_buf++;
-+ break;
-+ }
-+ printk("failed to parse vid value at %i (%s)\n", freq_index, curr_buf);
-+ return -EINVAL;
-+ }
-+
-+ state_index = freq_table[freq_index].index;
-+ original_control = data->original_controls[state_index];
-+ original_vid = original_control & INTEL_MSR_VID_MASK;
-+ if (new_vid <= original_vid) {
-+ new_control = (original_control & ~INTEL_MSR_VID_MASK) | new_vid;
-+ dprintk("setting control at %i to %x (default is %x)\n",
-+ freq_index, new_control, original_control);
-+ acpi_data->states[state_index].control = new_control;
-+
-+ } else {
-+ printk("skipping vid at %i, %u is greater than default %u\n",
-+ freq_index, new_vid, original_vid);
-+ }
-+
-+ curr_buf = next_buf;
-+ while ((curr_buf - buf < count) && ((*curr_buf == ' ') || (*curr_buf == ','))) {
-+ curr_buf++;
-+ }
-+ }
-+
-+ /* set new voltage at current frequency */
-+ data->resume = 1;
-+ acpi_cpufreq_target(policy, get_cur_freq_on_cpu(policy->cpu), CPUFREQ_RELATION_L);
-+
-+ return curr_buf - buf;
-+}
-+
-+static ssize_t store_freq_attr_controls(struct cpufreq_policy *policy, const char *buf, size_t count)
-+{
-+ struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
-+ struct acpi_processor_performance *acpi_data;
-+ struct cpufreq_frequency_table *freq_table;
-+ const char *curr_buf;
-+ unsigned int op_count;
-+ unsigned int state_index;
-+ int isok;
-+ char *next_buf;
-+ ssize_t retval;
-+ unsigned int new_vid;
-+ unsigned int original_vid;
-+ unsigned int new_fid;
-+ unsigned int old_fid;
-+ unsigned int original_control;
-+ unsigned int old_control;
-+ unsigned int new_control;
-+ int found;
-+
-+ if (unlikely(data == NULL ||
-+ data->acpi_data == NULL ||
-+ data->freq_table == NULL ||
-+ data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
-+ return -ENODEV;
-+ }
-+
-+ retval = check_origial_table(data);
-+ if (0 != retval)
-+ return retval;
-+
-+ acpi_data = data->acpi_data;
-+ freq_table = data->freq_table;
-+
-+ op_count = 0;
-+ curr_buf = buf;
-+ next_buf = NULL;
-+ isok = 1;
-+
-+ while ( (isok) && (curr_buf != NULL) )
-+ {
-+ op_count++;
-+ // Parse fid
-+ new_fid = simple_strtoul(curr_buf, &next_buf, 10);
-+ if ((next_buf != curr_buf) && (next_buf != NULL))
-+ {
-+ // Parse separator between frequency and voltage
-+ curr_buf = next_buf;
-+ next_buf = NULL;
-+ if (*curr_buf==':')
-+ {
-+ curr_buf++;
-+ // Parse vid
-+ new_vid = simple_strtoul(curr_buf, &next_buf, 10);
-+ if ((next_buf != curr_buf) && (next_buf != NULL))
-+ {
-+ found = 0;
-+ for (state_index = 0; state_index < acpi_data->state_count; state_index++) {
-+ old_control = acpi_data->states[state_index].control;
-+ old_fid = extract_fid_from_control(old_control);
-+ if (new_fid == old_fid)
-+ {
-+ found = 1;
-+ original_control = data->original_controls[state_index];
-+ original_vid = extract_vid_from_control(original_control);
-+ if (new_vid <= original_vid)
-+ {
-+ new_control = (original_control & ~INTEL_MSR_VID_MASK) | new_vid;
-+ dprintk("setting control at %i to %x (default is %x)\n",
-+ state_index, new_control, original_control);
-+ acpi_data->states[state_index].control = new_control;
-+
-+ } else {
-+ printk("skipping vid at %i, %u is greater than default %u\n",
-+ state_index, new_vid, original_vid);
-+ }
-+ }
-+ }
-+
-+ if (found == 0)
-+ {
-+ printk("operating point # %u not found (FID = %u)\n", op_count, new_fid);
-+ isok = 0;
-+ }
-+
-+ // Parse seprator before next operating point, if any
-+ curr_buf = next_buf;
-+ next_buf = NULL;
-+ if ((*curr_buf == ',') || (*curr_buf == ' '))
-+ curr_buf++;
-+ else
-+ curr_buf = NULL;
-+ }
-+ else
-+ {
-+ printk("failed to parse VID of operating point # %u (%s)\n", op_count, curr_buf);
-+ isok = 0;
-+ }
-+ }
-+ else
-+ {
-+ printk("failed to parse operating point # %u (%s)\n", op_count, curr_buf);
-+ isok = 0;
-+ }
-+ }
-+ else
-+ {
-+ printk("failed to parse FID of operating point # %u (%s)\n", op_count, curr_buf);
-+ isok = 0;
-+ }
-+ }
-+
-+ if (isok)
-+ {
-+ retval = count;
-+ /* set new voltage at current frequency */
-+ data->resume = 1;
-+ acpi_cpufreq_target(policy, get_cur_freq_on_cpu(policy->cpu), CPUFREQ_RELATION_L);
-+ }
-+ else
-+ {
-+ retval = -EINVAL;
-+ }
-+
-+ return retval;
-+}
-+
-+static ssize_t show_freq_attr_phc_version(struct cpufreq_policy *policy, char *buf)
-+{
-+ ssize_t count = 0;
-+ count += sprintf(&buf[count], "%s\n", PHC_VERSION_STRING);
-+ return count;
-+}
-+
-+static struct freq_attr cpufreq_freq_attr_phc_version =
-+{
-+ .attr = { .name = "phc_version", .mode = 0444, .owner = THIS_MODULE },
-+ .show = show_freq_attr_phc_version,
-+ .store = NULL,
-+};
-+
-+static struct freq_attr cpufreq_freq_attr_vids =
-+{
-+ .attr = { .name = "phc_vids", .mode = 0644, .owner = THIS_MODULE },
-+ .show = show_freq_attr_vids,
-+ .store = store_freq_attr_vids,
-+};
-+
-+static struct freq_attr cpufreq_freq_attr_default_vids =
-+{
-+ .attr = { .name = "phc_default_vids", .mode = 0444, .owner = THIS_MODULE },
-+ .show = show_freq_attr_default_vids,
-+ .store = NULL,
-+};
-+
-+static struct freq_attr cpufreq_freq_attr_fids =
-+{
-+ .attr = { .name = "phc_fids", .mode = 0444, .owner = THIS_MODULE },
-+ .show = show_freq_attr_fids,
-+ .store = NULL,
-+};
-+
-+static struct freq_attr cpufreq_freq_attr_controls =
-+{
-+ .attr = { .name = "phc_controls", .mode = 0644, .owner = THIS_MODULE },
-+ .show = show_freq_attr_controls,
-+ .store = store_freq_attr_controls,
-+};
-+
-+static struct freq_attr cpufreq_freq_attr_default_controls =
-+{
-+ .attr = { .name = "phc_default_controls", .mode = 0444, .owner = THIS_MODULE },
-+ .show = show_freq_attr_default_controls,
-+ .store = NULL,
-+};
-+
-+
- static struct freq_attr *acpi_cpufreq_attr[] = {
-+ &cpufreq_freq_attr_phc_version,
- &cpufreq_freq_attr_scaling_available_freqs,
-+ &cpufreq_freq_attr_vids,
-+ &cpufreq_freq_attr_default_vids,
-+ &cpufreq_freq_attr_fids,
-+ &cpufreq_freq_attr_controls,
-+ &cpufreq_freq_attr_default_controls,
- NULL,
- };
-
- static struct cpufreq_driver acpi_cpufreq_driver = {
- .verify = acpi_cpufreq_verify,
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part1.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part1.patch
deleted file mode 100644
index e239571..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part1.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
-index 47c6be8..a55a1c9 100644
---- a/drivers/char/Kconfig
-+++ b/drivers/char/Kconfig
-@@ -58,6 +58,49 @@ config VT_CONSOLE
-
- If unsure, say Y.
-
-+config VT_CKO
-+ bool "Colored kernel message output"
-+ depends on VT_CONSOLE
-+ ---help---
-+ This option enables kernel messages to be emitted in
-+ colors other than the default.
-+ This option enlarges your kernel by approximately 1/2 KB.
-+
-+ If unsure, say N.
-+
-+config VT_PRINTK_COLOR
-+ hex "Colored kernel message output"
-+ range 0x00 0xFF
-+ depends on VT_CKO
-+ default 0x07
-+ ---help---
-+ This option defines with which color kernel messages will be
-+ printed to the console.
-+
-+ The value you need to enter here is the value is composed
-+ (OR-ed) of a foreground and a background color.
-+
-+ Foreground:
-+ 0x00 = black, 0x08 = dark gray,
-+ 0x01 = red, 0x09 = light red,
-+ 0x02 = green, 0x0A = light green,
-+ 0x03 = brown, 0x0B = yellow,
-+ 0x04 = blue, 0x0C = light blue,
-+ 0x05 = magenta, 0x0D = light magenta,
-+ 0x06 = cyan, 0x0E = light cyan,
-+ 0x07 = gray, 0x0F = white,
-+
-+ (Foreground colors 0x08 to 0x0F do not work when a VGA
-+ console font with 512 glyphs is used.)
-+
-+ Background:
-+ 0x00 = black, 0x40 = blue,
-+ 0x10 = red, 0x50 = magenta,
-+ 0x20 = green, 0x60 = cyan,
-+ 0x30 = brown, 0x70 = gray,
-+
-+ For example, 0x1F would yield white on red.
-+
- config HW_CONSOLE
- bool
- depends on VT && !S390 && !UML
-diff --git a/drivers/char/vt.c b/drivers/char/vt.c
-index 159c9e2..cf61236 100644
---- a/drivers/char/vt.c
-+++ b/drivers/char/vt.c
-@@ -73,6 +73,7 @@
- */
-
- #include <linux/module.h>
-+#include <linux/moduleparam.h>
- #include <linux/types.h>
- #include <linux/sched.h>
- #include <linux/tty.h>
-@@ -2392,6 +2393,24 @@ struct tty_driver *console_driver;
-
- #ifdef CONFIG_VT_CONSOLE
-
-+#ifdef CONFIG_VT_CKO
-+static unsigned int printk_color __read_mostly = CONFIG_VT_PRINTK_COLOR;
-+module_param(printk_color, uint, S_IRUGO | S_IWUSR);
-+
-+static void vc_set_color(struct vc_data *vc, unsigned char color)
-+{
-+ vc->vc_color = color_table[color & 0xF] |
-+ (color_table[(color >> 4) & 0x7] << 4) |
-+ (color & 0x80);
-+ update_attr(vc);
-+}
-+#else
-+static const unsigned int printk_color;
-+static inline void vc_set_color(const struct vc_data *vc, unsigned char c)
-+{
-+}
-+#endif
-+
- /*
- * Console on virtual terminal
- *
-@@ -2434,6 +2453,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
- hide_cursor(vc);
-
- start = (ushort *)vc->vc_pos;
-+ vc_set_color(vc, printk_color);
-
- /* Contrived structure to try to emulate original need_wrap behaviour
- * Problems caused when we have need_wrap set on '\n' character */
-@@ -2482,6 +2502,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
- }
- }
- set_cursor(vc);
-+ vc_set_color(vc, vc->vc_def_color);
- notify_update(vc);
-
- quit:
---
-To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at http://vger.kernel.org/majordomo-info.html
-Please read the FAQ at http://www.tux.org/lkml/
-
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part2.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part2.patch
deleted file mode 100644
index 231e9d0..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part2.patch
+++ /dev/null
@@ -1,220 +0,0 @@
-diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
-index cff84cd..ba137a4 100644
---- a/arch/x86/kernel/early_printk.c
-+++ b/arch/x86/kernel/early_printk.c
-@@ -15,7 +15,8 @@
- static int max_ypos = 25, max_xpos = 80;
- static int current_ypos = 25, current_xpos = 0;
-
--static void early_vga_write(struct console *con, const char *str, unsigned n)
-+static void early_vga_write(struct console *con, const char *str, unsigned n,
-+ unsigned int loglevel)
- {
- char c;
- int i, k, j;
-@@ -84,7 +85,8 @@ static int early_serial_putc(unsigned char ch)
- return timeout ? 0 : -1;
- }
-
--static void early_serial_write(struct console *con, const char *s, unsigned n)
-+static void early_serial_write(struct console *con, const char *s, unsigned n,
-+ unsigned int loglevel)
- {
- while (*s && n-- > 0) {
- if (*s == '\n')
-@@ -180,7 +182,8 @@ static void __init simnow_init(char *str)
- simnow_fd = simnow(XOPEN, (unsigned long)fn, O_WRONLY|O_APPEND|O_CREAT, 0644);
- }
-
--static void simnow_write(struct console *con, const char *s, unsigned n)
-+static void simnow_write(struct console *con, const char *s, unsigned n,
-+ unsigned int loglevel)
- {
- simnow(XWRITE, simnow_fd, (unsigned long)s, n);
- }
-@@ -204,7 +207,7 @@ void early_printk(const char *fmt, ...)
-
- va_start(ap,fmt);
- n = vscnprintf(buf,512,fmt,ap);
-- early_console->write(early_console,buf,n);
-+ early_console->write(early_console, buf, n, 0);
- va_end(ap);
- }
-
-diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
-index a55a1c9..3f5877e 100644
---- a/drivers/char/Kconfig
-+++ b/drivers/char/Kconfig
-@@ -75,7 +75,9 @@ config VT_PRINTK_COLOR
- default 0x07
- ---help---
- This option defines with which color kernel messages will be
-- printed to the console.
-+ printed to the console. This applies to all log levels.
-+ You can change the colors at run-time, or set them at boot-time
-+ using the "vt.printk_color" option.
-
- The value you need to enter here is the value is composed
- (OR-ed) of a foreground and a background color.
-diff --git a/drivers/char/vt.c b/drivers/char/vt.c
-index cf61236..75ca0cf 100644
---- a/drivers/char/vt.c
-+++ b/drivers/char/vt.c
-@@ -2394,8 +2394,17 @@ struct tty_driver *console_driver;
- #ifdef CONFIG_VT_CONSOLE
-
- #ifdef CONFIG_VT_CKO
--static unsigned int printk_color __read_mostly = CONFIG_VT_PRINTK_COLOR;
--module_param(printk_color, uint, S_IRUGO | S_IWUSR);
-+static unsigned int printk_color[8] __read_mostly = {
-+ CONFIG_VT_PRINTK_COLOR, /* KERN_EMERG */
-+ CONFIG_VT_PRINTK_COLOR, /* KERN_ALERT */
-+ CONFIG_VT_PRINTK_COLOR, /* KERN_CRIT */
-+ CONFIG_VT_PRINTK_COLOR, /* KERN_ERR */
-+ CONFIG_VT_PRINTK_COLOR, /* KERN_WARNING */
-+ CONFIG_VT_PRINTK_COLOR, /* KERN_NOTICE */
-+ CONFIG_VT_PRINTK_COLOR, /* KERN_INFO */
-+ CONFIG_VT_PRINTK_COLOR, /* KERN_DEBUG */
-+};
-+module_param_array(printk_color, uint, NULL, S_IRUGO | S_IWUSR);
-
- static void vc_set_color(struct vc_data *vc, unsigned char color)
- {
-@@ -2405,7 +2414,7 @@ static void vc_set_color(struct vc_data *vc, unsigned char color)
- update_attr(vc);
- }
- #else
--static const unsigned int printk_color;
-+static const unsigned int printk_color[8];
- static inline void vc_set_color(const struct vc_data *vc, unsigned char c)
- {
- }
-@@ -2417,10 +2426,11 @@ static inline void vc_set_color(const struct vc_data *vc, unsigned char c)
- * The console must be locked when we get here.
- */
-
--static void vt_console_print(struct console *co, const char *b, unsigned count)
-+static void vt_console_print(struct console *co, const char *b,
-+ unsigned int count, unsigned int loglevel)
- {
- struct vc_data *vc = vc_cons[fg_console].d;
-- unsigned char c;
-+ unsigned char current_color, c;
- static DEFINE_SPINLOCK(printing_lock);
- const ushort *start;
- ushort cnt = 0;
-@@ -2453,7 +2463,13 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
- hide_cursor(vc);
-
- start = (ushort *)vc->vc_pos;
-- vc_set_color(vc, printk_color);
-+
-+ /*
-+ * We always get a valid loglevel - <8> and "no level" is transformed
-+ * to <4> in the typical kernel.
-+ */
-+ current_color = printk_color[loglevel];
-+ vc_set_color(vc, current_color);
-
- /* Contrived structure to try to emulate original need_wrap behaviour
- * Problems caused when we have need_wrap set on '\n' character */
-diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
-index 665341e..ae04e77 100644
---- a/drivers/net/netconsole.c
-+++ b/drivers/net/netconsole.c
-@@ -694,7 +694,8 @@ static struct notifier_block netconsole_netdev_notifier = {
- .notifier_call = netconsole_netdev_event,
- };
-
--static void write_msg(struct console *con, const char *msg, unsigned int len)
-+static void write_msg(struct console *con, const char *msg, unsigned int len,
-+ unsigned int loglevel)
- {
- int frag, left;
- unsigned long flags;
-diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
-index 77f7a7f..21a0ebf 100644
---- a/drivers/serial/8250.c
-+++ b/drivers/serial/8250.c
-@@ -2466,7 +2466,8 @@ static void serial8250_console_putchar(struct uart_port *port, int ch)
- * The console_lock must be held when we get here.
- */
- static void
--serial8250_console_write(struct console *co, const char *s, unsigned int count)
-+serial8250_console_write(struct console *co, const char *s, unsigned int count,
-+ unsigned int loglevel)
- {
- struct uart_8250_port *up = &serial8250_ports[co->index];
- unsigned long flags;
-diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c
-index 38776e8..88aa01c 100644
---- a/drivers/serial/8250_early.c
-+++ b/drivers/serial/8250_early.c
-@@ -83,7 +83,8 @@ static void __init serial_putc(struct uart_port *port, int c)
- }
-
- static void __init early_serial8250_write(struct console *console,
-- const char *s, unsigned int count)
-+ const char *s, unsigned int count,
-+ unsigned int loglevel)
- {
- struct uart_port *port = &early_device.port;
- unsigned int ier;
-diff --git a/include/linux/console.h b/include/linux/console.h
-index a5f88a6..23626e6 100644
---- a/include/linux/console.h
-+++ b/include/linux/console.h
-@@ -94,7 +94,8 @@ void give_up_console(const struct consw *sw);
-
- struct console {
- char name[16];
-- void (*write)(struct console *, const char *, unsigned);
-+ void (*write)(struct console *, const char *,
-+ unsigned int, unsigned int);
- int (*read)(struct console *, char *, unsigned);
- struct tty_driver *(*device)(struct console *, int *);
- void (*unblank)(void);
-diff --git a/kernel/printk.c b/kernel/printk.c
-index bdd4ea8..809ba4b 100644
---- a/kernel/printk.c
-+++ b/kernel/printk.c
-@@ -435,7 +435,8 @@ asmlinkage long sys_syslog(int type, char __user *buf, int len)
- /*
- * Call the console drivers on a range of log_buf
- */
--static void __call_console_drivers(unsigned start, unsigned end)
-+static void __call_console_drivers(unsigned int start, unsigned int end,
-+ unsigned int loglevel)
- {
- struct console *con;
-
-@@ -443,7 +444,7 @@ static void __call_console_drivers(unsigned start, unsigned end)
- if ((con->flags & CON_ENABLED) && con->write &&
- (cpu_online(smp_processor_id()) ||
- (con->flags & CON_ANYTIME)))
-- con->write(con, &LOG_BUF(start), end - start);
-+ con->write(con, &LOG_BUF(start), end - start, loglevel);
- }
- }
-
-@@ -470,10 +471,11 @@ static void _call_console_drivers(unsigned start,
- if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) {
- /* wrapped write */
- __call_console_drivers(start & LOG_BUF_MASK,
-- log_buf_len);
-- __call_console_drivers(0, end & LOG_BUF_MASK);
-+ log_buf_len, msg_log_level);
-+ __call_console_drivers(0, end & LOG_BUF_MASK,
-+ msg_log_level);
- } else {
-- __call_console_drivers(start, end);
-+ __call_console_drivers(start, end, msg_log_level);
- }
- }
- }
---
-To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at http://vger.kernel.org/majordomo-info.html
-Please read the FAQ at http://www.tux.org/lkml/
-
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part3.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part3.patch
deleted file mode 100644
index 06d9f6c..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/colored-printk-2.6.25.part3.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
-index 3f5877e..600c75a 100644
---- a/drivers/char/Kconfig
-+++ b/drivers/char/Kconfig
-@@ -58,28 +58,20 @@ config VT_CONSOLE
-
- If unsure, say Y.
-
--config VT_CKO
-+menuconfig VT_CKO
- bool "Colored kernel message output"
- depends on VT_CONSOLE
- ---help---
- This option enables kernel messages to be emitted in
- colors other than the default.
-+ You can also change the colors at run-time, or set them at boot-time
-+ using the "vt.printk_color" option.
-+
- This option enlarges your kernel by approximately 1/2 KB.
-
- If unsure, say N.
-
--config VT_PRINTK_COLOR
-- hex "Colored kernel message output"
-- range 0x00 0xFF
-- depends on VT_CKO
-- default 0x07
-- ---help---
-- This option defines with which color kernel messages will be
-- printed to the console. This applies to all log levels.
-- You can change the colors at run-time, or set them at boot-time
-- using the "vt.printk_color" option.
--
-- The value you need to enter here is the value is composed
-+ The value you need to enter is the value is composed
- (OR-ed) of a foreground and a background color.
-
- Foreground:
-@@ -103,6 +95,74 @@ config VT_PRINTK_COLOR
-
- For example, 0x1F would yield white on red.
-
-+if VT_CKO
-+
-+config VT_PRINTK_EMERG_COLOR
-+ hex 'Color for "emergency" level'
-+ range 0x00 0xFF
-+ default 0x07
-+ ---help---
-+ This option defines in which color kernel emergency messages
-+ will be printed to the console.
-+
-+config VT_PRINTK_ALERT_COLOR
-+ hex 'Color for "alert" level'
-+ range 0x00 0xFF
-+ default 0x07
-+ ---help---
-+ This option defines in which color kernel alert messages
-+ will be printed to the console.
-+
-+config VT_PRINTK_CRIT_COLOR
-+ hex 'Color for "critical" level'
-+ range 0x00 0xFF
-+ default 0x07
-+ ---help---
-+ This option defines in which color critical kernel messages
-+ will be printed to the console.
-+
-+config VT_PRINTK_ERROR_COLOR
-+ hex 'Color for "error" level'
-+ range 0x00 0xFF
-+ default 0x07
-+ ---help---
-+ This option defines in which color kernel error messages
-+ will be printed to the console.
-+
-+config VT_PRINTK_WARNING_COLOR
-+ hex 'Color for "warning" level'
-+ range 0x00 0xFF
-+ default 0x07
-+ ---help---
-+ This option defines in which color kernel warning messages
-+ will be printed to the console.
-+
-+config VT_PRINTK_NOTICE_COLOR
-+ hex 'Color for "notice" level'
-+ range 0x00 0xFF
-+ default 0x07
-+ ---help---
-+ This option defines in which color kernel notices
-+ will be printed to the console.
-+
-+config VT_PRINTK_INFO_COLOR
-+ hex 'Color for "info" level'
-+ range 0x00 0xFF
-+ default 0x07
-+ ---help---
-+ This option defines in which color informational kernel messages
-+ will be printed to the console.
-+
-+config VT_PRINTK_DEBUG_COLOR
-+ hex 'Color for "debug" level'
-+ range 0x00 0xFF
-+ default 0x07
-+ ---help---
-+ This option defines in which color kernel debugging messages
-+ will be printed to the console.
-+
-+endif # VT_CKO
-+
- config HW_CONSOLE
- bool
- depends on VT && !S390 && !UML
-diff --git a/drivers/char/vt.c b/drivers/char/vt.c
-index 75ca0cf..a3f2ff3 100644
---- a/drivers/char/vt.c
-+++ b/drivers/char/vt.c
-@@ -2395,14 +2395,14 @@ struct tty_driver *console_driver;
-
- #ifdef CONFIG_VT_CKO
- static unsigned int printk_color[8] __read_mostly = {
-- CONFIG_VT_PRINTK_COLOR, /* KERN_EMERG */
-- CONFIG_VT_PRINTK_COLOR, /* KERN_ALERT */
-- CONFIG_VT_PRINTK_COLOR, /* KERN_CRIT */
-- CONFIG_VT_PRINTK_COLOR, /* KERN_ERR */
-- CONFIG_VT_PRINTK_COLOR, /* KERN_WARNING */
-- CONFIG_VT_PRINTK_COLOR, /* KERN_NOTICE */
-- CONFIG_VT_PRINTK_COLOR, /* KERN_INFO */
-- CONFIG_VT_PRINTK_COLOR, /* KERN_DEBUG */
-+ CONFIG_VT_PRINTK_EMERG_COLOR,
-+ CONFIG_VT_PRINTK_ALERT_COLOR,
-+ CONFIG_VT_PRINTK_CRIT_COLOR,
-+ CONFIG_VT_PRINTK_ERROR_COLOR,
-+ CONFIG_VT_PRINTK_WARNING_COLOR,
-+ CONFIG_VT_PRINTK_NOTICE_COLOR,
-+ CONFIG_VT_PRINTK_INFO_COLOR,
-+ CONFIG_VT_PRINTK_DEBUG_COLOR,
- };
- module_param_array(printk_color, uint, NULL, S_IRUGO | S_IWUSR);
-
---
-To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at http://vger.kernel.org/majordomo-info.html
-Please read the FAQ at http://www.tux.org/lkml/
-
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/kernel-2.6.25-export-init_mm.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/kernel-2.6.25-export-init_mm.patch
deleted file mode 100644
index 5f95a6b..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/kernel-2.6.25-export-init_mm.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- arch/x86/kernel/init_task.c.orig 2008-04-17 04:49:44.000000000 +0200
-+++ arch/x86/kernel/init_task.c 2008-04-17 23:52:15.000000000 +0200
-@@ -15,7 +15,7 @@
- static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
- static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
- struct mm_struct init_mm = INIT_MM(init_mm);
--EXPORT_UNUSED_SYMBOL(init_mm); /* will be removed in 2.6.26 */
-+EXPORT_SYMBOL(init_mm); /* will be removed in 2.6.26 */ // temporary kludge
-
- /*
- * Initial thread structure.
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/kernel-2.6.25-rcu-license.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/kernel-2.6.25-rcu-license.patch
deleted file mode 100644
index fbdb7c2..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/kernel-2.6.25-rcu-license.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- kernel/rcupreempt.c.orig 2008-04-17 04:49:44.000000000 +0200
-+++ kernel/rcupreempt.c 2008-04-19 12:27:19.000000000 +0200
-@@ -283,7 +283,7 @@
- local_irq_restore(flags);
- }
- }
--EXPORT_SYMBOL_GPL(__rcu_read_lock);
-+EXPORT_SYMBOL(__rcu_read_lock);
-
- void __rcu_read_unlock(void)
- {
-@@ -353,7 +353,7 @@
- local_irq_restore(flags);
- }
- }
--EXPORT_SYMBOL_GPL(__rcu_read_unlock);
-+EXPORT_SYMBOL(__rcu_read_unlock);
-
- /*
- * If a global counter flip has occurred since the last time that we
diff --git a/sys-kernel/thinkpad-sources/files/2.6.25-r1/linux-2.6.25-iwl-merge.patch b/sys-kernel/thinkpad-sources/files/2.6.25-r1/linux-2.6.25-iwl-merge.patch
deleted file mode 100644
index f000009..0000000
--- a/sys-kernel/thinkpad-sources/files/2.6.25-r1/linux-2.6.25-iwl-merge.patch
+++ /dev/null
@@ -1,124255 +0,0 @@
-diff -Nbur linux-2.6.25.old/Documentation/DocBook/mac80211.tmpl linux-2.6.25/Documentation/DocBook/mac80211.tmpl
---- linux-2.6.25.old/Documentation/DocBook/mac80211.tmpl 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.25/Documentation/DocBook/mac80211.tmpl 2008-04-19 13:54:59.000000000 +0200
-@@ -0,0 +1,335 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-+
-+<book id="mac80211-developers-guide">
-+ <bookinfo>
-+ <title>The mac80211 subsystem for kernel developers</title>
-+
-+ <authorgroup>
-+ <author>
-+ <firstname>Johannes</firstname>
-+ <surname>Berg</surname>
-+ <affiliation>
-+ <address><email>johannes@sipsolutions.net</email></address>
-+ </affiliation>
-+ </author>
-+ </authorgroup>
-+
-+ <copyright>
-+ <year>2007</year>
-+ <year>2008</year>
-+ <holder>Johannes Berg</holder>
-+ </copyright>
-+
-+ <legalnotice>
-+ <para>
-+ This documentation is free software; you can redistribute
-+ it and/or modify it under the terms of the GNU General Public
-+ License version 2 as published by the Free Software Foundation.
-+ </para>
-+
-+ <para>
-+ This documentation is distributed in the hope that it will be
-+ useful, but WITHOUT ANY WARRANTY; without even the implied
-+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+ See the GNU General Public License for more details.
-+ </para>
-+
-+ <para>
-+ You should have received a copy of the GNU General Public
-+ License along with this documentation; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-+ MA 02111-1307 USA
-+ </para>
-+
-+ <para>
-+ For more details see the file COPYING in the source
-+ distribution of Linux.
-+ </para>
-+ </legalnotice>
-+
-+ <abstract>
-+!Pinclude/net/mac80211.h Introduction
-+!Pinclude/net/mac80211.h Warning
-+ </abstract>
-+ </bookinfo>
-+
-+ <toc></toc>
-+
-+<!--
-+Generally, this document shall be ordered by increasing complexity.
-+It is important to note that readers should be able to read only
-+the first few sections to get a working driver and only advanced
-+usage should require reading the full document.
-+-->
-+
-+ <part>
-+ <title>The basic mac80211 driver interface</title>
-+ <partintro>
-+ <para>
-+ You should read and understand the information contained
-+ within this part of the book while implementing a driver.
-+ In some chapters, advanced usage is noted, that may be
-+ skipped at first.
-+ </para>
-+ <para>
-+ This part of the book only covers station and monitor mode
-+ functionality, additional information required to implement
-+ the other modes is covered in the second part of the book.
-+ </para>
-+ </partintro>
-+
-+ <chapter id="basics">
-+ <title>Basic hardware handling</title>
-+ <para>TBD</para>
-+ <para>
-+ This chapter shall contain information on getting a hw
-+ struct allocated and registered with mac80211.
-+ </para>
-+ <para>
-+ Since it is required to allocate rates/modes before registering
-+ a hw struct, this chapter shall also contain information on setting
-+ up the rate/mode structs.
-+ </para>
-+ <para>
-+ Additionally, some discussion about the callbacks and
-+ the general programming model should be in here, including
-+ the definition of ieee80211_ops which will be referred to
-+ a lot.
-+ </para>
-+ <para>
-+ Finally, a discussion of hardware capabilities should be done
-+ with references to other parts of the book.
-+ </para>
-+<!-- intentionally multiple !F lines to get proper order -->
-+!Finclude/net/mac80211.h ieee80211_hw
-+!Finclude/net/mac80211.h ieee80211_hw_flags
-+!Finclude/net/mac80211.h SET_IEEE80211_DEV
-+!Finclude/net/mac80211.h SET_IEEE80211_PERM_ADDR
-+!Finclude/net/mac80211.h ieee80211_ops
-+!Finclude/net/mac80211.h ieee80211_alloc_hw
-+!Finclude/net/mac80211.h ieee80211_register_hw
-+!Finclude/net/mac80211.h ieee80211_get_tx_led_name
-+!Finclude/net/mac80211.h ieee80211_get_rx_led_name
-+!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
-+!Finclude/net/mac80211.h ieee80211_get_radio_led_name
-+!Finclude/net/mac80211.h ieee80211_unregister_hw
-+!Finclude/net/mac80211.h ieee80211_free_hw
-+ </chapter>
-+
-+ <chapter id="phy-handling">
-+ <title>PHY configuration</title>
-+ <para>TBD</para>
-+ <para>
-+ This chapter should describe PHY handling including
-+ start/stop callbacks and the various structures used.
-+ </para>
-+!Finclude/net/mac80211.h ieee80211_conf
-+!Finclude/net/mac80211.h ieee80211_conf_flags
-+ </chapter>
-+
-+ <chapter id="iface-handling">
-+ <title>Virtual interfaces</title>
-+ <para>TBD</para>
-+ <para>
-+ This chapter should describe virtual interface basics
-+ that are relevant to the driver (VLANs, MGMT etc are not.)
-+ It should explain the use of the add_iface/remove_iface
-+ callbacks as well as the interface configuration callbacks.
-+ </para>
-+ <para>Things related to AP mode should be discussed there.</para>
-+ <para>
-+ Things related to supporting multiple interfaces should be
-+ in the appropriate chapter, a BIG FAT note should be here about
-+ this though and the recommendation to allow only a single
-+ interface in STA mode at first!
-+ </para>
-+!Finclude/net/mac80211.h ieee80211_if_types
-+!Finclude/net/mac80211.h ieee80211_if_init_conf
-+!Finclude/net/mac80211.h ieee80211_if_conf
-+ </chapter>
-+
-+ <chapter id="rx-tx">
-+ <title>Receive and transmit processing</title>
-+ <sect1>
-+ <title>what should be here</title>
-+ <para>TBD</para>
-+ <para>
-+ This should describe the receive and transmit
-+ paths in mac80211/the drivers as well as
-+ transmit status handling.
-+ </para>
-+ </sect1>
-+ <sect1>
-+ <title>Frame format</title>
-+!Pinclude/net/mac80211.h Frame format
-+ </sect1>
-+ <sect1>
-+ <title>Alignment issues</title>
-+ <para>TBD</para>
-+ </sect1>
-+ <sect1>
-+ <title>Calling into mac80211 from interrupts</title>
-+!Pinclude/net/mac80211.h Calling mac80211 from interrupts
-+ </sect1>
-+ <sect1>
-+ <title>functions/definitions</title>
-+!Finclude/net/mac80211.h ieee80211_rx_status
-+!Finclude/net/mac80211.h mac80211_rx_flags
-+!Finclude/net/mac80211.h ieee80211_tx_control
-+!Finclude/net/mac80211.h ieee80211_tx_status_flags
-+!Finclude/net/mac80211.h ieee80211_rx
-+!Finclude/net/mac80211.h ieee80211_rx_irqsafe
-+!Finclude/net/mac80211.h ieee80211_tx_status
-+!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe
-+!Finclude/net/mac80211.h ieee80211_rts_get
-+!Finclude/net/mac80211.h ieee80211_rts_duration
-+!Finclude/net/mac80211.h ieee80211_ctstoself_get
-+!Finclude/net/mac80211.h ieee80211_ctstoself_duration
-+!Finclude/net/mac80211.h ieee80211_generic_frame_duration
-+!Finclude/net/mac80211.h ieee80211_get_hdrlen_from_skb
-+!Finclude/net/mac80211.h ieee80211_get_hdrlen
-+!Finclude/net/mac80211.h ieee80211_wake_queue
-+!Finclude/net/mac80211.h ieee80211_stop_queue
-+!Finclude/net/mac80211.h ieee80211_start_queues
-+!Finclude/net/mac80211.h ieee80211_stop_queues
-+!Finclude/net/mac80211.h ieee80211_wake_queues
-+ </sect1>
-+ </chapter>
-+
-+ <chapter id="filters">
-+ <title>Frame filtering</title>
-+!Pinclude/net/mac80211.h Frame filtering
-+!Finclude/net/mac80211.h ieee80211_filter_flags
-+ </chapter>
-+ </part>
-+
-+ <part id="advanced">
-+ <title>Advanced driver interface</title>
-+ <partintro>
-+ <para>
-+ Information contained within this part of the book is
-+ of interest only for advanced interaction of mac80211
-+ with drivers to exploit more hardware capabilities and
-+ improve performance.
-+ </para>
-+ </partintro>
-+
-+ <chapter id="hardware-crypto-offload">
-+ <title>Hardware crypto acceleration</title>
-+!Pinclude/net/mac80211.h Hardware crypto acceleration
-+<!-- intentionally multiple !F lines to get proper order -->
-+!Finclude/net/mac80211.h set_key_cmd
-+!Finclude/net/mac80211.h ieee80211_key_conf
-+!Finclude/net/mac80211.h ieee80211_key_alg
-+!Finclude/net/mac80211.h ieee80211_key_flags
-+ </chapter>
-+
-+ <chapter id="qos">
-+ <title>Multiple queues and QoS support</title>
-+ <para>TBD</para>
-+!Finclude/net/mac80211.h ieee80211_tx_queue_params
-+!Finclude/net/mac80211.h ieee80211_tx_queue_stats_data
-+!Finclude/net/mac80211.h ieee80211_tx_queue
-+ </chapter>
-+
-+ <chapter id="AP">
-+ <title>Access point mode support</title>
-+ <para>TBD</para>
-+ <para>Some parts of the if_conf should be discussed here instead</para>
-+ <para>
-+ Insert notes about VLAN interfaces with hw crypto here or
-+ in the hw crypto chapter.
-+ </para>
-+!Finclude/net/mac80211.h ieee80211_get_buffered_bc
-+!Finclude/net/mac80211.h ieee80211_beacon_get
-+ </chapter>
-+
-+ <chapter id="multi-iface">
-+ <title>Supporting multiple virtual interfaces</title>
-+ <para>TBD</para>
-+ <para>
-+ Note: WDS with identical MAC address should almost always be OK
-+ </para>
-+ <para>
-+ Insert notes about having multiple virtual interfaces with
-+ different MAC addresses here, note which configurations are
-+ supported by mac80211, add notes about supporting hw crypto
-+ with it.
-+ </para>
-+ </chapter>
-+
-+ <chapter id="hardware-scan-offload">
-+ <title>Hardware scan offload</title>
-+ <para>TBD</para>
-+!Finclude/net/mac80211.h ieee80211_scan_completed
-+ </chapter>
-+ </part>
-+
-+ <part id="rate-control">
-+ <title>Rate control interface</title>
-+ <partintro>
-+ <para>TBD</para>
-+ <para>
-+ This part of the book describes the rate control algorithm
-+ interface and how it relates to mac80211 and drivers.
-+ </para>
-+ </partintro>
-+ <chapter id="dummy">
-+ <title>dummy chapter</title>
-+ <para>TBD</para>
-+ </chapter>
-+ </part>
-+
-+ <part id="internal">
-+ <title>Internals</title>
-+ <partintro>
-+ <para>TBD</para>
-+ <para>
-+ This part of the book describes mac80211 internals.
-+ </para>
-+ </partintro>
-+
-+ <chapter id="key-handling">
-+ <title>Key handling</title>
-+ <sect1>
-+ <title>Key handling basics</title>
-+!Pnet/mac80211/key.c Key handling basics
-+ </sect1>
-+ <sect1>
-+ <title>MORE TBD</title>
-+ <para>TBD</para>
-+ </sect1>
-+ </chapter>
-+
-+ <chapter id="rx-processing">
-+ <title>Receive processing</title>
-+ <para>TBD</para>
-+ </chapter>
-+
-+ <chapter id="tx-processing">
-+ <title>Transmit processing</title>
-+ <para>TBD</para>
-+ </chapter>
-+
-+ <chapter id="sta-info">
-+ <title>Station info handling</title>
-+ <sect1>
-+ <title>Programming information</title>
-+!Fnet/mac80211/sta_info.h sta_info
-+!Fnet/mac80211/sta_info.h ieee80211_sta_info_flags
-+ </sect1>
-+ <sect1>
-+ <title>STA information lifetime rules</title>
-+!Pnet/mac80211/sta_info.c STA information lifetime rules
-+ </sect1>
-+ </chapter>
-+
-+ <chapter id="synchronisation">
-+ <title>Synchronisation</title>
-+ <para>TBD</para>
-+ <para>Locking, lots of RCU</para>
-+ </chapter>
-+ </part>
-+</book>
-diff -Nbur linux-2.6.25.old/Documentation/DocBook/Makefile linux-2.6.25/Documentation/DocBook/Makefile
---- linux-2.6.25.old/Documentation/DocBook/Makefile 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/Documentation/DocBook/Makefile 2008-04-19 16:23:24.000000000 +0200
-@@ -11,7 +11,8 @@
- procfs-guide.xml writing_usb_driver.xml networking.xml \
- kernel-api.xml filesystems.xml lsm.xml usb.xml \
- gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
-- genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml
-+ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
-+ mac80211.xml
-
- ###
- # The build process is as follows (targets):
-diff -Nbur linux-2.6.25.old/Documentation/feature-removal-schedule.txt linux-2.6.25/Documentation/feature-removal-schedule.txt
---- linux-2.6.25.old/Documentation/feature-removal-schedule.txt 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/Documentation/feature-removal-schedule.txt 2008-04-19 16:23:24.000000000 +0200
-@@ -230,33 +230,6 @@
-
- ---------------------------
-
--What: bcm43xx wireless network driver
--When: 2.6.26
--Files: drivers/net/wireless/bcm43xx
--Why: This driver's functionality has been replaced by the
-- mac80211-based b43 and b43legacy drivers.
--Who: John W. Linville <linville@tuxdriver.com>
--
-----------------------------
--
--What: ieee80211 softmac wireless networking component
--When: 2.6.26 (or after removal of bcm43xx and port of zd1211rw to mac80211)
--Files: net/ieee80211/softmac
--Why: No in-kernel drivers will depend on it any longer.
--Who: John W. Linville <linville@tuxdriver.com>
--
-----------------------------
--
--What: rc80211-simple rate control algorithm for mac80211
--When: 2.6.26
--Files: net/mac80211/rc80211-simple.c
--Why: This algorithm was provided for reference but always exhibited bad
-- responsiveness and performance and has some serious flaws. It has been
-- replaced by rc80211-pid.
--Who: Stefano Brivio <stefano.brivio@polimi.it>
--
-----------------------------
--
- What (Why):
- - include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files
- (superseded by xt_TOS/xt_tos target & match)
-diff -Nbur linux-2.6.25.old/Documentation/laptops/acer-wmi.txt linux-2.6.25/Documentation/laptops/acer-wmi.txt
---- linux-2.6.25.old/Documentation/laptops/acer-wmi.txt 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/Documentation/laptops/acer-wmi.txt 2008-04-19 13:54:59.000000000 +0200
-@@ -80,7 +80,7 @@
- e.g. With the BCM4318 on the Acer Aspire 5020 series:
-
- ndiswrapper: Light blinks on when transmitting
--bcm43xx/b43: Solid light, blinks off when transmitting
-+b43: Solid light, blinks off when transmitting
-
- Wireless radio control is unconditionally enabled - all Acer laptops that support
- acer-wmi come with built-in wireless. However, should you feel so inclined to
-diff -Nbur linux-2.6.25.old/Documentation/networking/bcm43xx.txt linux-2.6.25/Documentation/networking/bcm43xx.txt
---- linux-2.6.25.old/Documentation/networking/bcm43xx.txt 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/Documentation/networking/bcm43xx.txt 1970-01-01 01:00:00.000000000 +0100
-@@ -1,89 +0,0 @@
--
-- BCM43xx Linux Driver Project
-- ============================
--
--Introduction
--------------
--
--Many of the wireless devices found in modern notebook computers are
--based on the wireless chips produced by Broadcom. These devices have
--been a problem for Linux users as there is no open-source driver
--available. In addition, Broadcom has not released specifications
--for the device, and driver availability has been limited to the
--binary-only form used in the GPL versions of AP hardware such as the
--Linksys WRT54G, and the Windows and OS X drivers. Before this project
--began, the only way to use these devices were to use the Windows or
--OS X drivers with either the Linuxant or ndiswrapper modules. There
--is a strong penalty if this method is used as loading the binary-only
--module "taints" the kernel, and no kernel developer will help diagnose
--any kernel problems.
--
--Development
-------------
--
--This driver has been developed using
--a clean-room technique that is described at
--http://bcm-specs.sipsolutions.net/ReverseEngineeringProcess. For legal
--reasons, none of the clean-room crew works on the on the Linux driver,
--and none of the Linux developers sees anything but the specifications,
--which are the ultimate product of the reverse-engineering group.
--
--Software
----------
--
--Since the release of the 2.6.17 kernel, the bcm43xx driver has been
--distributed with the kernel source, and is prebuilt in most, if not
--all, distributions. There is, however, additional software that is
--required. The firmware used by the chip is the intellectual property
--of Broadcom and they have not given the bcm43xx team redistribution
--rights to this firmware. Since we cannot legally redistribute
--the firmware we cannot include it with the driver. Furthermore, it
--cannot be placed in the downloadable archives of any distributing
--organization; therefore, the user is responsible for obtaining the
--firmware and placing it in the appropriate location so that the driver
--can find it when initializing.
--
--To help with this process, the bcm43xx developers provide a separate
--program named bcm43xx-fwcutter to "cut" the firmware out of a
--Windows or OS X driver and write the extracted files to the proper
--location. This program is usually provided with the distribution;
--however, it may be downloaded from
--
--http://developer.berlios.de/project/showfiles.php?group_id=4547
--
--The firmware is available in two versions. V3 firmware is used with
--the in-kernel bcm43xx driver that uses a software MAC layer called
--SoftMAC, and will have a microcode revision of 0x127 or smaller. The
--V4 firmware is used by an out-of-kernel driver employing a variation of
--the Devicescape MAC layer known as d80211. Once bcm43xx-d80211 reaches
--a satisfactory level of development, it will replace bcm43xx-softmac
--in the kernel as it is much more flexible and powerful.
--
--A source for the latest V3 firmware is
--
--http://downloads.openwrt.org/sources/wl_apsta-3.130.20.0.o
--
--Once this file is downloaded, the command
--'bcm43xx-fwcutter -w <dir> <filename>'
--will extract the microcode and write it to directory
--<dir>. The correct directory will depend on your distribution;
--however, most use '/lib/firmware'. Once this step is completed,
--the bcm3xx driver should load when the system is booted. To see
--any messages relating to the driver, issue the command 'dmesg |
--grep bcm43xx' from a terminal window. If there are any problems,
--please send that output to Bcm43xx-dev@lists.berlios.de.
--
--Although the driver has been in-kernel since 2.6.17, the earliest
--version is quite limited in its capability. Patches that include
--all features of later versions are available for the stable kernel
--versions from 2.6.18. These will be needed if you use a BCM4318,
--or a PCI Express version (BCM4311 and BCM4312). In addition, if you
--have an early BCM4306 and more than 1 GB RAM, your kernel will need
--to be patched. These patches, which are being updated regularly,
--are available at ftp://lwfinger.dynalias.org/patches. Look for
--combined_2.6.YY.patch. Of course you will need kernel source downloaded
--from kernel.org, or the source from your distribution.
--
--If you build your own kernel, please enable CONFIG_BCM43XX_DEBUG
--and CONFIG_IEEE80211_SOFTMAC_DEBUG. The log information provided is
--essential for solving any problems.
-diff -Nbur linux-2.6.25.old/drivers/net/ps3_gelic_wireless.c linux-2.6.25/drivers/net/ps3_gelic_wireless.c
---- linux-2.6.25.old/drivers/net/ps3_gelic_wireless.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/ps3_gelic_wireless.c 2008-04-19 16:24:28.000000000 +0200
-@@ -87,7 +87,7 @@
-
- static inline int precise_ie(void)
- {
-- return 0; /* FIXME */
-+ return (0 <= ps3_compare_firmware_version(2, 2, 0));
- }
- /*
- * post_eurus_cmd helpers
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/adm8211.c linux-2.6.25/drivers/net/wireless/adm8211.c
---- linux-2.6.25.old/drivers/net/wireless/adm8211.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/adm8211.c 2008-04-19 13:54:59.000000000 +0200
-@@ -48,6 +48,32 @@
- { 0 }
- };
-
-+static struct ieee80211_rate adm8211_rates[] = {
-+ { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-+ { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-+ { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-+ { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-+ { .bitrate = 220, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, /* XX ?? */
-+};
-+
-+static const struct ieee80211_channel adm8211_channels[] = {
-+ { .center_freq = 2412},
-+ { .center_freq = 2417},
-+ { .center_freq = 2422},
-+ { .center_freq = 2427},
-+ { .center_freq = 2432},
-+ { .center_freq = 2437},
-+ { .center_freq = 2442},
-+ { .center_freq = 2447},
-+ { .center_freq = 2452},
-+ { .center_freq = 2457},
-+ { .center_freq = 2462},
-+ { .center_freq = 2467},
-+ { .center_freq = 2472},
-+ { .center_freq = 2484},
-+};
-+
-+
- static void adm8211_eeprom_register_read(struct eeprom_93cx6 *eeprom)
- {
- struct adm8211_priv *priv = eeprom->data;
-@@ -155,17 +181,17 @@
- printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n",
- pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max);
-
-- priv->modes[0].num_channels = chan_range.max - chan_range.min + 1;
-- priv->modes[0].channels = priv->channels;
-+ BUILD_BUG_ON(sizeof(priv->channels) != sizeof(adm8211_channels));
-
-- memcpy(priv->channels, adm8211_channels, sizeof(adm8211_channels));
-+ memcpy(priv->channels, adm8211_channels, sizeof(priv->channels));
-+ priv->band.channels = priv->channels;
-+ priv->band.n_channels = ARRAY_SIZE(adm8211_channels);
-+ priv->band.bitrates = adm8211_rates;
-+ priv->band.n_bitrates = ARRAY_SIZE(adm8211_rates);
-
- for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++)
-- if (i >= chan_range.min && i <= chan_range.max)
-- priv->channels[i - 1].flag =
-- IEEE80211_CHAN_W_SCAN |
-- IEEE80211_CHAN_W_ACTIVE_SCAN |
-- IEEE80211_CHAN_W_IBSS;
-+ if (i < chan_range.min || i > chan_range.max)
-+ priv->channels[i - 1].flags |= IEEE80211_CHAN_DISABLED;
-
- switch (priv->eeprom->specific_bbptype) {
- case ADM8211_BBP_RFMD3000:
-@@ -347,7 +373,6 @@
- unsigned int pktlen;
- struct sk_buff *skb, *newskb;
- unsigned int limit = priv->rx_ring_size;
-- static const u8 rate_tbl[] = {10, 20, 55, 110, 220};
- u8 rssi, rate;
-
- while (!(priv->rx_ring[entry].status & cpu_to_le32(RDES0_STATUS_OWN))) {
-@@ -425,12 +450,10 @@
- else
- rx_status.ssi = 100 - rssi;
-
-- if (rate <= 4)
-- rx_status.rate = rate_tbl[rate];
-+ rx_status.rate_idx = rate;
-
-- rx_status.channel = priv->channel;
-- rx_status.freq = adm8211_channels[priv->channel - 1].freq;
-- rx_status.phymode = MODE_IEEE80211B;
-+ rx_status.freq = adm8211_channels[priv->channel - 1].center_freq;
-+ rx_status.band = IEEE80211_BAND_2GHZ;
-
- ieee80211_rx_irqsafe(dev, skb, &rx_status);
- }
-@@ -465,9 +488,6 @@
- if (stsr & ADM8211_STSR_TCI)
- adm8211_interrupt_tci(dev);
-
-- /*ADM8211_INT(LinkOn);*/
-- /*ADM8211_INT(LinkOff);*/
--
- ADM8211_INT(PCF);
- ADM8211_INT(BCNTC);
- ADM8211_INT(GPINT);
-@@ -477,7 +497,6 @@
- ADM8211_INT(SQL);
- ADM8211_INT(WEPTD);
- ADM8211_INT(ATIME);
-- /*ADM8211_INT(TBTT);*/
- ADM8211_INT(TEIS);
- ADM8211_INT(FBE);
- ADM8211_INT(REIS);
-@@ -485,9 +504,6 @@
- ADM8211_INT(RPS);
- ADM8211_INT(RDU);
- ADM8211_INT(TUF);
-- /*ADM8211_INT(TRT);*/
-- /*ADM8211_INT(TLT);*/
-- /*ADM8211_INT(TDU);*/
- ADM8211_INT(TPS);
-
- return IRQ_HANDLED;
-@@ -1054,7 +1070,7 @@
- if (priv->pdev->revision != ADM8211_REV_BA) {
- rate_buf[0] = ARRAY_SIZE(adm8211_rates);
- for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++)
-- rate_buf[i + 1] = (adm8211_rates[i].rate / 5) | 0x80;
-+ rate_buf[i + 1] = (adm8211_rates[i].bitrate / 5) | 0x80;
- } else {
- /* workaround for rev BA specific bug */
- rate_buf[0] = 0x04;
-@@ -1086,7 +1102,7 @@
- u32 reg;
- u8 cline;
-
-- reg = le32_to_cpu(ADM8211_CSR_READ(PAR));
-+ reg = ADM8211_CSR_READ(PAR);
- reg |= ADM8211_PAR_MRLE | ADM8211_PAR_MRME;
- reg &= ~(ADM8211_PAR_BAR | ADM8211_PAR_CAL);
-
-@@ -1303,9 +1319,10 @@
- static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
- {
- struct adm8211_priv *priv = dev->priv;
-+ int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
-
-- if (conf->channel != priv->channel) {
-- priv->channel = conf->channel;
-+ if (channel != priv->channel) {
-+ priv->channel = channel;
- adm8211_rf_set_channel(dev, priv->channel);
- }
-
-@@ -1678,13 +1695,9 @@
- int plcp, dur, len, plcp_signal, short_preamble;
- struct ieee80211_hdr *hdr;
-
-- if (control->tx_rate < 0) {
-- short_preamble = 1;
-- plcp_signal = -control->tx_rate;
-- } else {
-- short_preamble = 0;
-- plcp_signal = control->tx_rate;
-- }
-+ short_preamble = !!(control->tx_rate->flags &
-+ IEEE80211_TXCTL_SHORT_PREAMBLE);
-+ plcp_signal = control->tx_rate->bitrate;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED;
-@@ -1880,18 +1893,11 @@
- SET_IEEE80211_PERM_ADDR(dev, perm_addr);
-
- dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
-- dev->flags = IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED;
-- /* IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
-+ /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
-
- dev->channel_change_time = 1000;
- dev->max_rssi = 100; /* FIXME: find better value */
-
-- priv->modes[0].mode = MODE_IEEE80211B;
-- /* channel info filled in by adm8211_read_eeprom */
-- memcpy(priv->rates, adm8211_rates, sizeof(adm8211_rates));
-- priv->modes[0].num_rates = ARRAY_SIZE(adm8211_rates);
-- priv->modes[0].rates = priv->rates;
--
- dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */
-
- priv->retry_limit = 3;
-@@ -1917,14 +1923,9 @@
- goto err_free_desc;
- }
-
-- priv->channel = priv->modes[0].channels[0].chan;
-+ priv->channel = 1;
-
-- err = ieee80211_register_hwmode(dev, &priv->modes[0]);
-- if (err) {
-- printk(KERN_ERR "%s (adm8211): Can't register hwmode\n",
-- pci_name(pdev));
-- goto err_free_desc;
-- }
-+ dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
-
- err = ieee80211_register_hw(dev);
- if (err) {
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/adm8211.h linux-2.6.25/drivers/net/wireless/adm8211.h
---- linux-2.6.25.old/drivers/net/wireless/adm8211.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/adm8211.h 2008-04-19 13:54:59.000000000 +0200
-@@ -534,61 +534,6 @@
- u8 cis_data[0]; /* 0x80, 384 bytes */
- } __attribute__ ((packed));
-
--static const struct ieee80211_rate adm8211_rates[] = {
-- { .rate = 10,
-- .val = 10,
-- .val2 = -10,
-- .flags = IEEE80211_RATE_CCK_2 },
-- { .rate = 20,
-- .val = 20,
-- .val2 = -20,
-- .flags = IEEE80211_RATE_CCK_2 },
-- { .rate = 55,
-- .val = 55,
-- .val2 = -55,
-- .flags = IEEE80211_RATE_CCK_2 },
-- { .rate = 110,
-- .val = 110,
-- .val2 = -110,
-- .flags = IEEE80211_RATE_CCK_2 }
--};
--
--struct ieee80211_chan_range {
-- u8 min;
-- u8 max;
--};
--
--static const struct ieee80211_channel adm8211_channels[] = {
-- { .chan = 1,
-- .freq = 2412},
-- { .chan = 2,
-- .freq = 2417},
-- { .chan = 3,
-- .freq = 2422},
-- { .chan = 4,
-- .freq = 2427},
-- { .chan = 5,
-- .freq = 2432},
-- { .chan = 6,
-- .freq = 2437},
-- { .chan = 7,
-- .freq = 2442},
-- { .chan = 8,
-- .freq = 2447},
-- { .chan = 9,
-- .freq = 2452},
-- { .chan = 10,
-- .freq = 2457},
-- { .chan = 11,
-- .freq = 2462},
-- { .chan = 12,
-- .freq = 2467},
-- { .chan = 13,
-- .freq = 2472},
-- { .chan = 14,
-- .freq = 2484},
--};
--
- struct adm8211_priv {
- struct pci_dev *pdev;
- spinlock_t lock;
-@@ -603,9 +548,8 @@
- unsigned int cur_tx, dirty_tx, cur_rx;
-
- struct ieee80211_low_level_stats stats;
-- struct ieee80211_hw_mode modes[1];
-- struct ieee80211_channel channels[ARRAY_SIZE(adm8211_channels)];
-- struct ieee80211_rate rates[ARRAY_SIZE(adm8211_rates)];
-+ struct ieee80211_supported_band band;
-+ struct ieee80211_channel channels[14];
- int mode;
-
- int channel;
-@@ -643,6 +587,11 @@
- } transceiver_type;
- };
-
-+struct ieee80211_chan_range {
-+ u8 min;
-+ u8 max;
-+};
-+
- static const struct ieee80211_chan_range cranges[] = {
- {1, 11}, /* FCC */
- {1, 11}, /* IC */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/at76_usb.c linux-2.6.25/drivers/net/wireless/at76_usb.c
---- linux-2.6.25.old/drivers/net/wireless/at76_usb.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.25/drivers/net/wireless/at76_usb.c 2008-04-19 16:23:26.000000000 +0200
-@@ -0,0 +1,2518 @@
-+/*
-+ * at76c503/at76c505 USB driver
-+ *
-+ * Copyright (c) 2002 - 2003 Oliver Kurth
-+ * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de>
-+ * Copyright (c) 2004 Nick Jones
-+ * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
-+ * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
-+ * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of
-+ * the License, or (at your option) any later version.
-+ *
-+ * This file is part of the Berlios driver for WLAN USB devices based on the
-+ * Atmel AT76C503A/505/505A.
-+ *
-+ * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
-+ *
-+ * TODO for the mac80211 port:
-+ * o adhoc support
-+ * o RTS/CTS support
-+ * o Power Save Mode support
-+ * o support for short/long preambles
-+ * o export variables through debugfs/sysfs
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/spinlock.h>
-+#include <linux/list.h>
-+#include <linux/usb.h>
-+#include <linux/netdevice.h>
-+#include <linux/if_arp.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ethtool.h>
-+#include <linux/wireless.h>
-+#include <net/iw_handler.h>
-+#include <net/ieee80211_radiotap.h>
-+#include <linux/firmware.h>
-+#include <linux/leds.h>
-+#include <net/mac80211.h>
-+
-+#include "at76_usb.h"
-+
-+/* Version information */
-+#define DRIVER_NAME "at76_usb"
-+#define DRIVER_VERSION "0.17"
-+#define DRIVER_DESC "Atmel at76x USB Wireless LAN Driver"
-+
-+/* at76_debug bits */
-+#define DBG_PROGRESS 0x00000001 /* authentication/accociation */
-+#define DBG_BSS_TABLE 0x00000002 /* show BSS table after scans */
-+#define DBG_IOCTL 0x00000004 /* ioctl calls / settings */
-+#define DBG_MAC_STATE 0x00000008 /* MAC state transitions */
-+#define DBG_TX_DATA 0x00000010 /* tx header */
-+#define DBG_TX_DATA_CONTENT 0x00000020 /* tx content */
-+#define DBG_TX_MGMT 0x00000040 /* tx management */
-+#define DBG_RX_DATA 0x00000080 /* rx data header */
-+#define DBG_RX_DATA_CONTENT 0x00000100 /* rx data content */
-+#define DBG_RX_MGMT 0x00000200 /* rx mgmt frame headers */
-+#define DBG_RX_BEACON 0x00000400 /* rx beacon */
-+#define DBG_RX_CTRL 0x00000800 /* rx control */
-+#define DBG_RX_MGMT_CONTENT 0x00001000 /* rx mgmt content */
-+#define DBG_RX_FRAGS 0x00002000 /* rx data fragment handling */
-+#define DBG_DEVSTART 0x00004000 /* fw download, device start */
-+#define DBG_URB 0x00008000 /* rx urb status, ... */
-+#define DBG_RX_ATMEL_HDR 0x00010000 /* Atmel-specific Rx headers */
-+#define DBG_PROC_ENTRY 0x00020000 /* procedure entries/exits */
-+#define DBG_PM 0x00040000 /* power management settings */
-+#define DBG_BSS_MATCH 0x00080000 /* BSS match failures */
-+#define DBG_PARAMS 0x00100000 /* show configured parameters */
-+#define DBG_WAIT_COMPLETE 0x00200000 /* command completion */
-+#define DBG_RX_FRAGS_SKB 0x00400000 /* skb header of Rx fragments */
-+#define DBG_BSS_TABLE_RM 0x00800000 /* purging bss table entries */
-+#define DBG_MONITOR_MODE 0x01000000 /* monitor mode */
-+#define DBG_MIB 0x02000000 /* dump all MIBs on startup */
-+#define DBG_MGMT_TIMER 0x04000000 /* dump mgmt_timer ops */
-+#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */
-+#define DBG_FW 0x10000000 /* firmware download */
-+#define DBG_DFU 0x20000000 /* device firmware upgrade */
-+#define DBG_CMD 0x40000000
-+#define DBG_MAC80211 0x80000000
-+
-+#define DBG_DEFAULTS 0
-+
-+/* Use our own dbg macro */
-+#define at76_dbg(bits, format, arg...) \
-+ do { \
-+ if (at76_debug & (bits)) \
-+ printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
-+ } while (0)
-+
-+#define at76_dbg_dump(bits, buf, len, format, arg...) \
-+ do { \
-+ if (at76_debug & (bits)) { \
-+ printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
-+ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); \
-+ } \
-+ } while (0)
-+
-+static int at76_debug = DBG_DEFAULTS;
-+
-+/* Protect against concurrent firmware loading and parsing */
-+static struct mutex fw_mutex;
-+
-+static struct fwentry firmwares[] = {
-+ [0] = { "" },
-+ [BOARD_503_ISL3861] = { "atmel_at76c503-i3861.bin" },
-+ [BOARD_503_ISL3863] = { "atmel_at76c503-i3863.bin" },
-+ [BOARD_503] = { "atmel_at76c503-rfmd.bin" },
-+ [BOARD_503_ACC] = { "atmel_at76c503-rfmd-acc.bin" },
-+ [BOARD_505] = { "atmel_at76c505-rfmd.bin" },
-+ [BOARD_505_2958] = { "atmel_at76c505-rfmd2958.bin" },
-+ [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" },
-+ [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" },
-+};
-+
-+#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
-+
-+static struct usb_device_id dev_table[] = {
-+ /*
-+ * at76c503-i3861
-+ */
-+ /* Generic AT76C503/3861 device */
-+ { USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* Linksys WUSB11 v2.1/v2.6 */
-+ { USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* Netgear MA101 rev. A */
-+ { USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* Tekram U300C / Allnet ALL0193 */
-+ { USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* HP HN210W J7801A */
-+ { USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* Sitecom/Z-Com/Zyxel M4Y-750 */
-+ { USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* Dynalink/Askey WLL013 (intersil) */
-+ { USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
-+ { USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* BenQ AWL300 */
-+ { USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* Addtron AWU-120, Compex WLU11 */
-+ { USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* Intel AP310 AnyPoint II USB */
-+ { USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* Dynalink L11U */
-+ { USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* Arescom WL-210, FCC id 07J-GL2411USB */
-+ { USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* I-O DATA WN-B11/USB */
-+ { USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /* BT Voyager 1010 */
-+ { USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861) },
-+ /*
-+ * at76c503-i3863
-+ */
-+ /* Generic AT76C503/3863 device */
-+ { USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863) },
-+ /* Samsung SWL-2100U */
-+ { USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863) },
-+ /*
-+ * at76c503-rfmd
-+ */
-+ /* Generic AT76C503/RFMD device */
-+ { USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503) },
-+ /* Dynalink/Askey WLL013 (rfmd) */
-+ { USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503) },
-+ /* Linksys WUSB11 v2.6 */
-+ { USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503) },
-+ /* Network Everywhere NWU11B */
-+ { USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503) },
-+ /* Netgear MA101 rev. B */
-+ { USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503) },
-+ /* D-Link DWL-120 rev. E */
-+ { USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503) },
-+ /* Actiontec 802UAT1, HWU01150-01UK */
-+ { USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503) },
-+ /* AirVast W-Buddie WN210 */
-+ { USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503) },
-+ /* Dick Smith Electronics XH1153 802.11b USB adapter */
-+ { USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503) },
-+ /* CNet CNUSB611 */
-+ { USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503) },
-+ /* FiberLine FL-WL200U */
-+ { USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503) },
-+ /* BenQ AWL400 USB stick */
-+ { USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503) },
-+ /* 3Com 3CRSHEW696 */
-+ { USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503) },
-+ /* Siemens Santis ADSL WLAN USB adapter WLL 013 */
-+ { USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503) },
-+ /* Belkin F5D6050, version 2 */
-+ { USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503) },
-+ /* iBlitzz, BWU613 (not *B or *SB) */
-+ { USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503) },
-+ /* Gigabyte GN-WLBM101 */
-+ { USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503) },
-+ /* Planex GW-US11S */
-+ { USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503) },
-+ /* Internal WLAN adapter in h5[4,5]xx series iPAQs */
-+ { USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503) },
-+ /* Corega Wireless LAN USB-11 mini */
-+ { USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503) },
-+ /* Corega Wireless LAN USB-11 mini2 */
-+ { USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503) },
-+ /* Uniden PCW100 */
-+ { USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503) },
-+ /*
-+ * at76c503-rfmd-acc
-+ */
-+ /* SMC2664W */
-+ { USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC) },
-+ /* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
-+ { USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC) },
-+ /*
-+ * at76c505-rfmd
-+ */
-+ /* Generic AT76C505/RFMD */
-+ { USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505) },
-+ /*
-+ * at76c505-rfmd2958
-+ */
-+ /* Generic AT76C505/RFMD, OvisLink WL-1130USB */
-+ { USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
-+ /* Fiberline FL-WL240U */
-+ { USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958) },
-+ /* CNet CNUSB-611G */
-+ { USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958) },
-+ /* Linksys WUSB11 v2.8 */
-+ { USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958) },
-+ /* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
-+ { USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958) },
-+ /* Corega WLAN USB Stick 11 */
-+ { USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
-+ /* Microstar MSI Box MS6978 */
-+ { USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958) },
-+ /*
-+ * at76c505a-rfmd2958
-+ */
-+ /* Generic AT76C505A device */
-+ { USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A) },
-+ /* Generic AT76C505AS device */
-+ { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) },
-+ /* Siemens Gigaset USB WLAN Adapter 11 */
-+ { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) },
-+ /*
-+ * at76c505amx-rfmd
-+ */
-+ /* Generic AT76C505AMX device */
-+ { USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX) },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(usb, dev_table);
-+
-+/* Supported rates of this hardware, bit 7 marks basic rates */
-+static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
-+
-+static const char *const preambles[] = { "long", "short", "auto" };
-+
-+/* Firmware download */
-+/* DFU states */
-+#define STATE_IDLE 0x00
-+#define STATE_DETACH 0x01
-+#define STATE_DFU_IDLE 0x02
-+#define STATE_DFU_DOWNLOAD_SYNC 0x03
-+#define STATE_DFU_DOWNLOAD_BUSY 0x04
-+#define STATE_DFU_DOWNLOAD_IDLE 0x05
-+#define STATE_DFU_MANIFEST_SYNC 0x06
-+#define STATE_DFU_MANIFEST 0x07
-+#define STATE_DFU_MANIFEST_WAIT_RESET 0x08
-+#define STATE_DFU_UPLOAD_IDLE 0x09
-+#define STATE_DFU_ERROR 0x0a
-+
-+/* DFU commands */
-+#define DFU_DETACH 0
-+#define DFU_DNLOAD 1
-+#define DFU_UPLOAD 2
-+#define DFU_GETSTATUS 3
-+#define DFU_CLRSTATUS 4
-+#define DFU_GETSTATE 5
-+#define DFU_ABORT 6
-+
-+#define FW_BLOCK_SIZE 1024
-+
-+struct dfu_status {
-+ unsigned char status;
-+ unsigned char poll_timeout[3];
-+ unsigned char state;
-+ unsigned char string;
-+} __attribute__((packed));
-+
-+static inline int at76_is_intersil(enum board_type board)
-+{
-+ return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
-+}
-+
-+static inline int at76_is_503rfmd(enum board_type board)
-+{
-+ return (board == BOARD_503 || board == BOARD_503_ACC);
-+}
-+
-+static inline int at76_is_505a(enum board_type board)
-+{
-+ return (board == BOARD_505A || board == BOARD_505AMX);
-+}
-+
-+/* Load a block of the first (internal) part of the firmware */
-+static int at76_load_int_fw_block(struct usb_device *udev, int blockno,
-+ void *block, int size)
-+{
-+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), DFU_DNLOAD,
-+ USB_TYPE_CLASS | USB_DIR_OUT |
-+ USB_RECIP_INTERFACE, blockno, 0, block, size,
-+ USB_CTRL_GET_TIMEOUT);
-+}
-+
-+static int at76_dfu_get_status(struct usb_device *udev,
-+ struct dfu_status *status)
-+{
-+ int ret;
-+
-+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATUS,
-+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
-+ 0, 0, status, sizeof(struct dfu_status),
-+ USB_CTRL_GET_TIMEOUT);
-+ return ret;
-+}
-+
-+static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
-+{
-+ int ret;
-+
-+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATE,
-+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
-+ 0, 0, state, 1, USB_CTRL_GET_TIMEOUT);
-+ return ret;
-+}
-+
-+/* Convert timeout from the DFU status to jiffies */
-+static inline unsigned long at76_get_timeout(struct dfu_status *s)
-+{
-+ return msecs_to_jiffies((s->poll_timeout[2] << 16)
-+ | (s->poll_timeout[1] << 8)
-+ | (s->poll_timeout[0]));
-+}
-+
-+/* Load internal firmware from the buffer. If manifest_sync_timeout > 0, use
-+ * its value in jiffies in the MANIFEST_SYNC state. */
-+static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
-+ int manifest_sync_timeout)
-+{
-+ u8 *block;
-+ struct dfu_status dfu_stat_buf;
-+ int ret = 0;
-+ int need_dfu_state = 1;
-+ int is_done = 0;
-+ u8 dfu_state = 0;
-+ u32 dfu_timeout = 0;
-+ int bsize = 0;
-+ int blockno = 0;
-+
-+ at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size,
-+ manifest_sync_timeout);
-+
-+ if (!size) {
-+ dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
-+ return -EINVAL;
-+ }
-+
-+ block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
-+ if (!block)
-+ return -ENOMEM;
-+
-+ do {
-+ if (need_dfu_state) {
-+ ret = at76_dfu_get_state(udev, &dfu_state);
-+ if (ret < 0) {
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "cannot get DFU state: %d\n", ret);
-+ goto exit;
-+ }
-+ need_dfu_state = 0;
-+ }
-+
-+ switch (dfu_state) {
-+ case STATE_DFU_DOWNLOAD_SYNC:
-+ at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC");
-+ ret = at76_dfu_get_status(udev, &dfu_stat_buf);
-+ if (ret >= 0) {
-+ dfu_state = dfu_stat_buf.state;
-+ dfu_timeout = at76_get_timeout(&dfu_stat_buf);
-+ need_dfu_state = 0;
-+ } else
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "at76_dfu_get_status returned %d\n",
-+ ret);
-+ break;
-+
-+ case STATE_DFU_DOWNLOAD_BUSY:
-+ at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
-+ need_dfu_state = 1;
-+
-+ at76_dbg(DBG_DFU, "DFU: Resetting device");
-+ schedule_timeout_interruptible(dfu_timeout);
-+ break;
-+
-+ case STATE_DFU_DOWNLOAD_IDLE:
-+ at76_dbg(DBG_DFU, "DOWNLOAD...");
-+ /* fall through */
-+ case STATE_DFU_IDLE:
-+ at76_dbg(DBG_DFU, "DFU IDLE");
-+
-+ bsize = min_t(int, size, FW_BLOCK_SIZE);
-+ memcpy(block, buf, bsize);
-+ at76_dbg(DBG_DFU, "int fw, size left = %5d, "
-+ "bsize = %4d, blockno = %2d", size, bsize,
-+ blockno);
-+ ret =
-+ at76_load_int_fw_block(udev, blockno, block, bsize);
-+ buf += bsize;
-+ size -= bsize;
-+ blockno++;
-+
-+ if (ret != bsize)
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "at76_load_int_fw_block "
-+ "returned %d\n", ret);
-+ need_dfu_state = 1;
-+ break;
-+
-+ case STATE_DFU_MANIFEST_SYNC:
-+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
-+
-+ ret = at76_dfu_get_status(udev, &dfu_stat_buf);
-+ if (ret < 0)
-+ break;
-+
-+ dfu_state = dfu_stat_buf.state;
-+ dfu_timeout = at76_get_timeout(&dfu_stat_buf);
-+ need_dfu_state = 0;
-+
-+ /* override the timeout from the status response,
-+ needed for AT76C505A */
-+ if (manifest_sync_timeout > 0)
-+ dfu_timeout = manifest_sync_timeout;
-+
-+ at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase");
-+ schedule_timeout_interruptible(dfu_timeout);
-+ break;
-+
-+ case STATE_DFU_MANIFEST:
-+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST");
-+ is_done = 1;
-+ break;
-+
-+ case STATE_DFU_MANIFEST_WAIT_RESET:
-+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
-+ is_done = 1;
-+ break;
-+
-+ case STATE_DFU_UPLOAD_IDLE:
-+ at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
-+ break;
-+
-+ case STATE_DFU_ERROR:
-+ at76_dbg(DBG_DFU, "STATE_DFU_ERROR");
-+ ret = -EPIPE;
-+ break;
-+
-+ default:
-+ at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
-+ ret = -EINVAL;
-+ break;
-+ }
-+ } while (!is_done && (ret >= 0));
-+
-+exit:
-+ kfree(block);
-+ if (ret >= 0)
-+ ret = 0;
-+
-+ return ret;
-+}
-+
-+#define HEX2STR_BUFFERS 4
-+#define HEX2STR_MAX_LEN 64
-+#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
-+
-+/* Convert binary data into hex string */
-+static char *hex2str(void *buf, int len)
-+{
-+ static atomic_t a = ATOMIC_INIT(0);
-+ static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
-+ char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)];
-+ char *obuf = ret;
-+ u8 *ibuf = buf;
-+
-+ if (len > HEX2STR_MAX_LEN)
-+ len = HEX2STR_MAX_LEN;
-+
-+ if (len <= 0) {
-+ ret[0] = '\0';
-+ return ret;
-+ }
-+
-+ while (len--) {
-+ *obuf++ = BIN2HEX(*ibuf >> 4);
-+ *obuf++ = BIN2HEX(*ibuf & 0xf);
-+ *obuf++ = '-';
-+ ibuf++;
-+ }
-+ *(--obuf) = '\0';
-+
-+ return ret;
-+}
-+
-+#define MAC2STR_BUFFERS 4
-+
-+static inline char *mac2str(u8 *mac)
-+{
-+ static atomic_t a = ATOMIC_INIT(0);
-+ static char bufs[MAC2STR_BUFFERS][6 * 3];
-+ char *str;
-+
-+ str = bufs[atomic_inc_return(&a) & (MAC2STR_BUFFERS - 1)];
-+ sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
-+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-+ return str;
-+}
-+
-+/* LED trigger */
-+static int tx_activity;
-+static void at76_ledtrig_tx_timerfunc(unsigned long data);
-+static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc, 0, 0);
-+DEFINE_LED_TRIGGER(ledtrig_tx);
-+
-+static void at76_ledtrig_tx_timerfunc(unsigned long data)
-+{
-+ static int tx_lastactivity;
-+
-+ if (tx_lastactivity != tx_activity) {
-+ tx_lastactivity = tx_activity;
-+ led_trigger_event(ledtrig_tx, LED_FULL);
-+ mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
-+ } else
-+ led_trigger_event(ledtrig_tx, LED_OFF);
-+}
-+
-+static void at76_ledtrig_tx_activity(void)
-+{
-+ tx_activity++;
-+ if (!timer_pending(&ledtrig_tx_timer))
-+ mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
-+}
-+
-+static int at76_remap(struct usb_device *udev)
-+{
-+ int ret;
-+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a,
-+ USB_TYPE_VENDOR | USB_DIR_OUT |
-+ USB_RECIP_INTERFACE, 0, 0, NULL, 0,
-+ USB_CTRL_GET_TIMEOUT);
-+ if (ret < 0)
-+ return ret;
-+ return 0;
-+}
-+
-+static int at76_get_op_mode(struct usb_device *udev)
-+{
-+ int ret;
-+ u8 op_mode;
-+
-+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
-+ USB_TYPE_VENDOR | USB_DIR_IN |
-+ USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1,
-+ USB_CTRL_GET_TIMEOUT);
-+ if (ret < 0)
-+ return ret;
-+ else if (ret < 1)
-+ return -EIO;
-+ else
-+ return op_mode;
-+}
-+
-+/* Load a block of the second ("external") part of the firmware */
-+static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno,
-+ void *block, int size)
-+{
-+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
-+ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
-+ 0x0802, blockno, block, size,
-+ USB_CTRL_GET_TIMEOUT);
-+}
-+
-+static inline int at76_get_hw_cfg(struct usb_device *udev,
-+ union at76_hwcfg *buf, int buf_size)
-+{
-+ return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
-+ USB_TYPE_VENDOR | USB_DIR_IN |
-+ USB_RECIP_INTERFACE, 0x0a02, 0,
-+ buf, buf_size, USB_CTRL_GET_TIMEOUT);
-+}
-+
-+/* Intersil boards use a different "value" for GetHWConfig requests */
-+static inline int at76_get_hw_cfg_intersil(struct usb_device *udev,
-+ union at76_hwcfg *buf, int buf_size)
-+{
-+ return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
-+ USB_TYPE_VENDOR | USB_DIR_IN |
-+ USB_RECIP_INTERFACE, 0x0902, 0,
-+ buf, buf_size, USB_CTRL_GET_TIMEOUT);
-+}
-+
-+/* Get the hardware configuration for the adapter and put it to the appropriate
-+ * fields of 'priv' (the GetHWConfig request and interpretation of the result
-+ * depends on the board type) */
-+static int at76_get_hw_config(struct at76_priv *priv)
-+{
-+ int ret;
-+ union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
-+
-+ if (!hwcfg)
-+ return -ENOMEM;
-+
-+ if (at76_is_intersil(priv->board_type)) {
-+ ret = at76_get_hw_cfg_intersil(priv->udev, hwcfg,
-+ sizeof(hwcfg->i));
-+ if (ret < 0)
-+ goto exit;
-+ memcpy(priv->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);
-+ priv->regulatory_domain = hwcfg->i.regulatory_domain;
-+ } else if (at76_is_503rfmd(priv->board_type)) {
-+ ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r3));
-+ if (ret < 0)
-+ goto exit;
-+ memcpy(priv->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);
-+ priv->regulatory_domain = hwcfg->r3.regulatory_domain;
-+ } else {
-+ ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r5));
-+ if (ret < 0)
-+ goto exit;
-+ memcpy(priv->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);
-+ priv->regulatory_domain = hwcfg->r5.regulatory_domain;
-+ }
-+
-+exit:
-+ kfree(hwcfg);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ return ret;
-+}
-+
-+static struct reg_domain const *at76_get_reg_domain(u16 code)
-+{
-+ int i;
-+ static struct reg_domain const fd_tab[] = {
-+ { 0x10, "FCC (USA)", 0x7ff }, /* ch 1-11 */
-+ { 0x20, "IC (Canada)", 0x7ff }, /* ch 1-11 */
-+ { 0x30, "ETSI (most of Europe)", 0x1fff }, /* ch 1-13 */
-+ { 0x31, "Spain", 0x600 }, /* ch 10-11 */
-+ { 0x32, "France", 0x1e00 }, /* ch 10-13 */
-+ { 0x40, "MKK (Japan)", 0x2000 }, /* ch 14 */
-+ { 0x41, "MKK1 (Japan)", 0x3fff }, /* ch 1-14 */
-+ { 0x50, "Israel", 0x3fc }, /* ch 3-9 */
-+ { 0x00, "<unknown>", 0xffffffff } /* ch 1-32 */
-+ };
-+
-+ /* Last entry is fallback for unknown domain code */
-+ for (i = 0; i < ARRAY_SIZE(fd_tab) - 1; i++)
-+ if (code == fd_tab[i].code)
-+ break;
-+
-+ return &fd_tab[i];
-+}
-+
-+static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
-+ int buf_size)
-+{
-+ int ret;
-+
-+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
-+ USB_TYPE_VENDOR | USB_DIR_IN |
-+ USB_RECIP_INTERFACE, mib << 8, 0, buf, buf_size,
-+ USB_CTRL_GET_TIMEOUT);
-+ if (ret >= 0 && ret != buf_size)
-+ return -EIO;
-+ return ret;
-+}
-+
-+/* Return positive number for status, negative for an error */
-+static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
-+{
-+ u8 stat_buf[40];
-+ int ret;
-+
-+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
-+ USB_TYPE_VENDOR | USB_DIR_IN |
-+ USB_RECIP_INTERFACE, cmd, 0, stat_buf,
-+ sizeof(stat_buf), USB_CTRL_GET_TIMEOUT);
-+ if (ret < 0)
-+ return ret;
-+
-+ return stat_buf[5];
-+}
-+
-+#define MAKE_CMD_CASE(c) case (c): return #c
-+
-+static const char *at76_get_cmd_string(u8 cmd_status)
-+{
-+ switch (cmd_status) {
-+ MAKE_CMD_CASE(CMD_SET_MIB);
-+ MAKE_CMD_CASE(CMD_GET_MIB);
-+ MAKE_CMD_CASE(CMD_SCAN);
-+ MAKE_CMD_CASE(CMD_JOIN);
-+ MAKE_CMD_CASE(CMD_START_IBSS);
-+ MAKE_CMD_CASE(CMD_RADIO_ON);
-+ MAKE_CMD_CASE(CMD_RADIO_OFF);
-+ MAKE_CMD_CASE(CMD_STARTUP);
-+ }
-+
-+ return "UNKNOWN";
-+}
-+
-+static int at76_set_card_command(struct usb_device *udev, int cmd, void *buf,
-+ int buf_size)
-+{
-+ int ret;
-+ struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) +
-+ buf_size, GFP_KERNEL);
-+
-+ if (!cmd_buf)
-+ return -ENOMEM;
-+
-+ cmd_buf->cmd = cmd;
-+ cmd_buf->reserved = 0;
-+ cmd_buf->size = cpu_to_le16(buf_size);
-+ memcpy(cmd_buf->data, buf, buf_size);
-+
-+ at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size,
-+ "issuing command %s (0x%02x)",
-+ at76_get_cmd_string(cmd), cmd);
-+
-+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
-+ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
-+ 0, 0, cmd_buf,
-+ sizeof(struct at76_command) + buf_size,
-+ USB_CTRL_GET_TIMEOUT);
-+ kfree(cmd_buf);
-+ return ret;
-+}
-+
-+#define MAKE_CMD_STATUS_CASE(c) case (c): return #c
-+static const char *at76_get_cmd_status_string(u8 cmd_status)
-+{
-+ switch (cmd_status) {
-+ MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE);
-+ MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE);
-+ MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN);
-+ MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER);
-+ MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED);
-+ MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT);
-+ MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS);
-+ MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE);
-+ MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED);
-+ }
-+
-+ return "UNKNOWN";
-+}
-+
-+/* Wait until the command is completed */
-+static int at76_wait_completion(struct at76_priv *priv, int cmd)
-+{
-+ int status = 0;
-+ unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT;
-+
-+ do {
-+ status = at76_get_cmd_status(priv->udev, cmd);
-+ if (status < 0) {
-+ printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), status);
-+ break;
-+ }
-+
-+ at76_dbg(DBG_WAIT_COMPLETE,
-+ "%s: Waiting on cmd %d, status = %d (%s)",
-+ wiphy_name(priv->hw->wiphy), cmd, status,
-+ at76_get_cmd_status_string(status));
-+
-+ if (status != CMD_STATUS_IN_PROGRESS
-+ && status != CMD_STATUS_IDLE)
-+ break;
-+
-+ schedule_timeout_interruptible(HZ / 10); /* 100 ms */
-+ if (time_after(jiffies, timeout)) {
-+ printk(KERN_ERR
-+ "%s: completion timeout for command %d\n",
-+ wiphy_name(priv->hw->wiphy), cmd);
-+ status = -ETIMEDOUT;
-+ break;
-+ }
-+ } while (1);
-+
-+ return status;
-+}
-+
-+static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
-+{
-+ int ret;
-+
-+ ret = at76_set_card_command(priv->udev, CMD_SET_MIB, buf,
-+ offsetof(struct set_mib_buffer,
-+ data) + buf->size);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at76_wait_completion(priv, CMD_SET_MIB);
-+ if (ret != CMD_STATUS_COMPLETE) {
-+ printk(KERN_INFO
-+ "%s: set_mib: at76_wait_completion failed "
-+ "with %d\n", wiphy_name(priv->hw->wiphy), ret);
-+ ret = -EIO;
-+ }
-+
-+ return ret;
-+}
-+
-+/* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
-+static int at76_set_radio(struct at76_priv *priv, int enable)
-+{
-+ int ret;
-+ int cmd;
-+
-+ if (priv->radio_on == enable)
-+ return 0;
-+
-+ cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF;
-+
-+ ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), cmd, ret);
-+ else
-+ ret = 1;
-+
-+ priv->radio_on = enable;
-+ return ret;
-+}
-+
-+/* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */
-+static int at76_set_pm_mode(struct at76_priv *priv)
-+{
-+ int ret = 0;
-+
-+ priv->mib_buf.type = MIB_MAC_MGMT;
-+ priv->mib_buf.size = 1;
-+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, power_mgmt_mode);
-+ priv->mib_buf.data.byte = priv->pm_mode;
-+
-+ ret = at76_set_mib(priv, &priv->mib_buf);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ return ret;
-+}
-+
-+/* Set the association id for power save mode */
-+static int at76_set_associd(struct at76_priv *priv, u16 id)
-+{
-+ int ret = 0;
-+
-+ priv->mib_buf.type = MIB_MAC_MGMT;
-+ priv->mib_buf.size = 2;
-+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id);
-+ priv->mib_buf.data.word = cpu_to_le16(id);
-+
-+ ret = at76_set_mib(priv, &priv->mib_buf);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: set_mib (associd) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ return ret;
-+}
-+
-+/* Set the listen interval for power save mode */
-+static int at76_set_listen_interval(struct at76_priv *priv, u16 interval)
-+{
-+ int ret = 0;
-+
-+ priv->mib_buf.type = MIB_MAC;
-+ priv->mib_buf.size = 2;
-+ priv->mib_buf.index = offsetof(struct mib_mac, listen_interval);
-+ priv->mib_buf.data.word = cpu_to_le16(interval);
-+
-+ ret = at76_set_mib(priv, &priv->mib_buf);
-+ if (ret < 0)
-+ printk(KERN_ERR
-+ "%s: set_mib (listen_interval) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ return ret;
-+}
-+
-+static int at76_set_preamble(struct at76_priv *priv, u8 type)
-+{
-+ int ret = 0;
-+
-+ priv->mib_buf.type = MIB_LOCAL;
-+ priv->mib_buf.size = 1;
-+ priv->mib_buf.index = offsetof(struct mib_local, preamble_type);
-+ priv->mib_buf.data.byte = type;
-+
-+ ret = at76_set_mib(priv, &priv->mib_buf);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ return ret;
-+}
-+
-+static int at76_set_frag(struct at76_priv *priv, u16 size)
-+{
-+ int ret = 0;
-+
-+ priv->mib_buf.type = MIB_MAC;
-+ priv->mib_buf.size = 2;
-+ priv->mib_buf.index = offsetof(struct mib_mac, frag_threshold);
-+ priv->mib_buf.data.word = cpu_to_le16(size);
-+
-+ ret = at76_set_mib(priv, &priv->mib_buf);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ return ret;
-+}
-+
-+static int at76_set_rts(struct at76_priv *priv, u16 size)
-+{
-+ int ret = 0;
-+
-+ priv->mib_buf.type = MIB_MAC;
-+ priv->mib_buf.size = 2;
-+ priv->mib_buf.index = offsetof(struct mib_mac, rts_threshold);
-+ priv->mib_buf.data.word = cpu_to_le16(size);
-+
-+ ret = at76_set_mib(priv, &priv->mib_buf);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ return ret;
-+}
-+
-+static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
-+{
-+ int ret = 0;
-+
-+ priv->mib_buf.type = MIB_LOCAL;
-+ priv->mib_buf.size = 1;
-+ priv->mib_buf.index = offsetof(struct mib_local, txautorate_fallback);
-+ priv->mib_buf.data.byte = onoff;
-+
-+ ret = at76_set_mib(priv, &priv->mib_buf);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ return ret;
-+}
-+
-+static int at76_add_mac_address(struct at76_priv *priv, void *addr)
-+{
-+ int ret = 0;
-+
-+ priv->mib_buf.type = MIB_MAC_ADDR;
-+ priv->mib_buf.size = ETH_ALEN;
-+ priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
-+ memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN);
-+
-+ ret = at76_set_mib(priv, &priv->mib_buf);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ return ret;
-+}
-+
-+static void at76_dump_mib_mac_addr(struct at76_priv *priv)
-+{
-+ int i;
-+ int ret;
-+ struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr),
-+ GFP_KERNEL);
-+
-+ if (!m)
-+ return;
-+
-+ ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
-+ sizeof(struct mib_mac_addr));
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
-+ wiphy_name(priv->hw->wiphy),
-+ mac2str(m->mac_addr), m->res[0], m->res[1]);
-+ for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
-+ at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
-+ "status %d", wiphy_name(priv->hw->wiphy), i,
-+ mac2str(m->group_addr[i]), m->group_addr_status[i]);
-+exit:
-+ kfree(m);
-+}
-+
-+static void at76_dump_mib_mac_wep(struct at76_priv *priv)
-+{
-+ int i;
-+ int ret;
-+ int key_len;
-+ struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
-+
-+ if (!m)
-+ return;
-+
-+ ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
-+ sizeof(struct mib_mac_wep));
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
-+ "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
-+ "encr_level %u key %d", wiphy_name(priv->hw->wiphy),
-+ m->privacy_invoked, m->wep_default_key_id,
-+ m->wep_key_mapping_len, m->exclude_unencrypted,
-+ le32_to_cpu(m->wep_icv_error_count),
-+ le32_to_cpu(m->wep_excluded_count), m->encryption_level,
-+ m->wep_default_key_id);
-+
-+ key_len = (m->encryption_level == 1) ?
-+ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
-+
-+ for (i = 0; i < WEP_KEYS; i++)
-+ at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
-+ wiphy_name(priv->hw->wiphy), i,
-+ hex2str(m->wep_default_keyvalue[i], key_len));
-+exit:
-+ kfree(m);
-+}
-+
-+static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
-+{
-+ int ret;
-+ struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt),
-+ GFP_KERNEL);
-+
-+ if (!m)
-+ return;
-+
-+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
-+ sizeof(struct mib_mac_mgmt));
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration "
-+ "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
-+ "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
-+ "current_bssid %s current_essid %s current_bss_type %d "
-+ "pm_mode %d ibss_change %d res %d "
-+ "multi_domain_capability_implemented %d "
-+ "international_roaming %d country_string %.3s",
-+ wiphy_name(priv->hw->wiphy), le16_to_cpu(m->beacon_period),
-+ le16_to_cpu(m->CFP_max_duration),
-+ le16_to_cpu(m->medium_occupancy_limit),
-+ le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
-+ m->CFP_mode, m->privacy_option_implemented, m->DTIM_period,
-+ m->CFP_period, mac2str(m->current_bssid),
-+ hex2str(m->current_essid, IW_ESSID_MAX_SIZE),
-+ m->current_bss_type, m->power_mgmt_mode, m->ibss_change,
-+ m->res, m->multi_domain_capability_implemented,
-+ m->multi_domain_capability_enabled, m->country_string);
-+exit:
-+ kfree(m);
-+}
-+
-+static void at76_dump_mib_mac(struct at76_priv *priv)
-+{
-+ int ret;
-+ struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
-+
-+ if (!m)
-+ return;
-+
-+ ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_MIB, "%s: MIB MAC: max_tx_msdu_lifetime %d "
-+ "max_rx_lifetime %d frag_threshold %d rts_threshold %d "
-+ "cwmin %d cwmax %d short_retry_time %d long_retry_time %d "
-+ "scan_type %d scan_channel %d probe_delay %u "
-+ "min_channel_time %d max_channel_time %d listen_int %d "
-+ "desired_ssid %s desired_bssid %s desired_bsstype %d",
-+ wiphy_name(priv->hw->wiphy),
-+ le32_to_cpu(m->max_tx_msdu_lifetime),
-+ le32_to_cpu(m->max_rx_lifetime),
-+ le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
-+ le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
-+ m->short_retry_time, m->long_retry_time, m->scan_type,
-+ m->scan_channel, le16_to_cpu(m->probe_delay),
-+ le16_to_cpu(m->min_channel_time),
-+ le16_to_cpu(m->max_channel_time),
-+ le16_to_cpu(m->listen_interval),
-+ hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE),
-+ mac2str(m->desired_bssid), m->desired_bsstype);
-+exit:
-+ kfree(m);
-+}
-+
-+static void at76_dump_mib_phy(struct at76_priv *priv)
-+{
-+ int ret;
-+ struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
-+
-+ if (!m)
-+ return;
-+
-+ ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_MIB, "%s: MIB PHY: ed_threshold %d slot_time %d "
-+ "sifs_time %d preamble_length %d plcp_header_length %d "
-+ "mpdu_max_length %d cca_mode_supported %d operation_rate_set "
-+ "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
-+ "phy_type %d current_reg_domain %d",
-+ wiphy_name(priv->hw->wiphy), le32_to_cpu(m->ed_threshold),
-+ le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
-+ le16_to_cpu(m->preamble_length),
-+ le16_to_cpu(m->plcp_header_length),
-+ le16_to_cpu(m->mpdu_max_length),
-+ le16_to_cpu(m->cca_mode_supported), m->operation_rate_set[0],
-+ m->operation_rate_set[1], m->operation_rate_set[2],
-+ m->operation_rate_set[3], m->channel_id, m->current_cca_mode,
-+ m->phy_type, m->current_reg_domain);
-+exit:
-+ kfree(m);
-+}
-+
-+static void at76_dump_mib_local(struct at76_priv *priv)
-+{
-+ int ret;
-+ struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
-+
-+ if (!m)
-+ return;
-+
-+ ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
-+ "txautorate_fallback %d ssid_size %d promiscuous_mode %d "
-+ "preamble_type %d", wiphy_name(priv->hw->wiphy),
-+ m->beacon_enable,
-+ m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
-+ m->preamble_type);
-+exit:
-+ kfree(m);
-+}
-+
-+static void at76_dump_mib_mdomain(struct at76_priv *priv)
-+{
-+ int ret;
-+ struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
-+
-+ if (!m)
-+ return;
-+
-+ ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
-+ sizeof(struct mib_mdomain));
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
-+ wiphy_name(priv->hw->wiphy),
-+ hex2str(m->channel_list, sizeof(m->channel_list)));
-+
-+ at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
-+ wiphy_name(priv->hw->wiphy),
-+ hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
-+exit:
-+ kfree(m);
-+}
-+
-+/* Enable monitor mode */
-+static int at76_start_monitor(struct at76_priv *priv)
-+{
-+ struct at76_req_scan scan;
-+ int ret;
-+
-+ memset(&scan, 0, sizeof(struct at76_req_scan));
-+ memset(scan.bssid, 0xff, ETH_ALEN);
-+
-+ scan.channel = priv->channel;
-+ scan.scan_type = SCAN_TYPE_PASSIVE;
-+ scan.international_scan = 0;
-+
-+ ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
-+ if (ret >= 0)
-+ ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
-+
-+ return ret;
-+}
-+
-+/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
-+ likely to compensate a flaw in the AT76C503A USB part ... */
-+static inline int at76_calc_padding(int wlen)
-+{
-+ /* add the USB TX header */
-+ wlen += AT76_TX_HDRLEN;
-+
-+ wlen = wlen % 64;
-+
-+ if (wlen < 50)
-+ return 50 - wlen;
-+
-+ if (wlen >= 61)
-+ return 64 + 50 - wlen;
-+
-+ return 0;
-+}
-+
-+static void at76_rx_callback(struct urb *urb)
-+{
-+ struct at76_priv *priv = urb->context;
-+
-+ priv->rx_tasklet.data = (unsigned long)urb;
-+ tasklet_schedule(&priv->rx_tasklet);
-+ return;
-+}
-+
-+static int at76_submit_rx_urb(struct at76_priv *priv)
-+{
-+ int ret;
-+ int size;
-+ struct sk_buff *skb = priv->rx_skb;
-+
-+ if (!priv->rx_urb) {
-+ printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
-+ wiphy_name(priv->hw->wiphy), __func__);
-+ return -EFAULT;
-+ }
-+
-+ if (!skb) {
-+ skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
-+ if (!skb) {
-+ printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
-+ wiphy_name(priv->hw->wiphy));
-+ ret = -ENOMEM;
-+ goto exit;
-+ }
-+ priv->rx_skb = skb;
-+ } else {
-+ skb_push(skb, skb_headroom(skb));
-+ skb_trim(skb, 0);
-+ }
-+
-+ size = skb_tailroom(skb);
-+ usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe,
-+ skb_put(skb, size), size, at76_rx_callback, priv);
-+ ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC);
-+ if (ret < 0) {
-+ if (ret == -ENODEV)
-+ at76_dbg(DBG_DEVSTART,
-+ "usb_submit_urb returned -ENODEV");
-+ else
-+ printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ }
-+
-+exit:
-+ if (ret < 0 && ret != -ENODEV)
-+ printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
-+ "driver and/or power cycle the device\n",
-+ wiphy_name(priv->hw->wiphy));
-+
-+ return ret;
-+}
-+
-+/* Download external firmware */
-+static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
-+{
-+ int ret;
-+ int op_mode;
-+ int blockno = 0;
-+ int bsize;
-+ u8 *block;
-+ u8 *buf = fwe->extfw;
-+ int size = fwe->extfw_size;
-+
-+ if (!buf || !size)
-+ return -ENOENT;
-+
-+ op_mode = at76_get_op_mode(udev);
-+ at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
-+
-+ if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
-+ dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n",
-+ op_mode);
-+ return -EINVAL;
-+ }
-+
-+ block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
-+ if (!block)
-+ return -ENOMEM;
-+
-+ at76_dbg(DBG_DEVSTART, "downloading external firmware");
-+
-+ /* for fw >= 0.100, the device needs an extra empty block */
-+ do {
-+ bsize = min_t(int, size, FW_BLOCK_SIZE);
-+ memcpy(block, buf, bsize);
-+ at76_dbg(DBG_DEVSTART,
-+ "ext fw, size left = %5d, bsize = %4d, blockno = %2d",
-+ size, bsize, blockno);
-+ ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
-+ if (ret != bsize) {
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "loading %dth firmware block failed: %d\n",
-+ blockno, ret);
-+ goto exit;
-+ }
-+ buf += bsize;
-+ size -= bsize;
-+ blockno++;
-+ } while (bsize > 0);
-+
-+ if (at76_is_505a(fwe->board_type)) {
-+ at76_dbg(DBG_DEVSTART, "200 ms delay for 505a");
-+ schedule_timeout_interruptible(HZ / 5 + 1);
-+ }
-+
-+exit:
-+ kfree(block);
-+ if (ret < 0)
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "downloading external firmware failed: %d\n", ret);
-+ return ret;
-+}
-+
-+/* Download internal firmware */
-+static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
-+{
-+ int ret;
-+ int need_remap = !at76_is_505a(fwe->board_type);
-+
-+ ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size,
-+ need_remap ? 0 : 2 * HZ);
-+
-+ if (ret < 0) {
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "downloading internal fw failed with %d\n", ret);
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_DEVSTART, "sending REMAP");
-+
-+ /* no REMAP for 505A (see SF driver) */
-+ if (need_remap) {
-+ ret = at76_remap(udev);
-+ if (ret < 0) {
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "sending REMAP failed with %d\n", ret);
-+ goto exit;
-+ }
-+ }
-+
-+ at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds");
-+ schedule_timeout_interruptible(2 * HZ + 1);
-+ usb_reset_device(udev);
-+
-+exit:
-+ return ret;
-+}
-+
-+static int at76_startup_device(struct at76_priv *priv)
-+{
-+ struct at76_card_config *ccfg = &priv->card_config;
-+ int ret;
-+
-+ at76_dbg(DBG_PARAMS,
-+ "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
-+ "keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size,
-+ priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE),
-+ priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
-+ priv->channel, priv->wep_enabled ? "enabled" : "disabled",
-+ priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
-+ at76_dbg(DBG_PARAMS,
-+ "%s param: preamble %s rts %d retry %d frag %d "
-+ "txrate %s auth_mode %d", wiphy_name(priv->hw->wiphy),
-+ preambles[priv->preamble_type], priv->rts_threshold,
-+ priv->short_retry_limit, priv->frag_threshold,
-+ priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
-+ TX_RATE_2MBIT ? "2MBit" : priv->txrate ==
-+ TX_RATE_5_5MBIT ? "5.5MBit" : priv->txrate ==
-+ TX_RATE_11MBIT ? "11MBit" : priv->txrate ==
-+ TX_RATE_AUTO ? "auto" : "<invalid>", priv->auth_mode);
-+ at76_dbg(DBG_PARAMS,
-+ "%s param: pm_mode %d pm_period %d auth_mode %s "
-+ "scan_times %d %d scan_mode %s",
-+ wiphy_name(priv->hw->wiphy), priv->pm_mode, priv->pm_period,
-+ priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
-+ priv->scan_min_time, priv->scan_max_time,
-+ priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
-+
-+ memset(ccfg, 0, sizeof(struct at76_card_config));
-+ ccfg->promiscuous_mode = 0;
-+ ccfg->short_retry_limit = priv->short_retry_limit;
-+
-+ if (priv->wep_enabled) {
-+ if (priv->wep_keys_len[priv->wep_key_id] > WEP_SMALL_KEY_LEN)
-+ ccfg->encryption_type = 2;
-+ else
-+ ccfg->encryption_type = 1;
-+
-+ /* jal: always exclude unencrypted if WEP is active */
-+ ccfg->exclude_unencrypted = 1;
-+ } else {
-+ ccfg->exclude_unencrypted = 0;
-+ ccfg->encryption_type = 0;
-+ }
-+
-+ ccfg->rts_threshold = cpu_to_le16(priv->rts_threshold);
-+ ccfg->fragmentation_threshold = cpu_to_le16(priv->frag_threshold);
-+
-+ memcpy(ccfg->basic_rate_set, hw_rates, 4);
-+ /* jal: really needed, we do a set_mib for autorate later ??? */
-+ ccfg->auto_rate_fallback = (priv->txrate == TX_RATE_AUTO ? 1 : 0);
-+ ccfg->channel = priv->channel;
-+ ccfg->privacy_invoked = priv->wep_enabled;
-+ memcpy(ccfg->current_ssid, priv->essid, IW_ESSID_MAX_SIZE);
-+ ccfg->ssid_len = priv->essid_size;
-+
-+ ccfg->wep_default_key_id = priv->wep_key_id;
-+ memcpy(ccfg->wep_default_key_value, priv->wep_keys,
-+ sizeof(priv->wep_keys));
-+
-+ ccfg->short_preamble = priv->preamble_type;
-+ ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
-+
-+ ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
-+ sizeof(struct at76_card_config));
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ return ret;
-+ }
-+
-+ at76_wait_completion(priv, CMD_STARTUP);
-+
-+ /* remove BSSID from previous run */
-+ memset(priv->bssid, 0, ETH_ALEN);
-+
-+ if (at76_set_radio(priv, 1) == 1)
-+ at76_wait_completion(priv, CMD_RADIO_ON);
-+
-+ ret = at76_set_preamble(priv, priv->preamble_type);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at76_set_frag(priv, priv->frag_threshold);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at76_set_rts(priv, priv->rts_threshold);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at76_set_autorate_fallback(priv,
-+ priv->txrate == TX_RATE_AUTO ? 1 : 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = at76_set_pm_mode(priv);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (at76_debug & DBG_MIB) {
-+ at76_dump_mib_mac(priv);
-+ at76_dump_mib_mac_addr(priv);
-+ at76_dump_mib_mac_mgmt(priv);
-+ at76_dump_mib_mac_wep(priv);
-+ at76_dump_mib_mdomain(priv);
-+ at76_dump_mib_phy(priv);
-+ at76_dump_mib_local(priv);
-+ }
-+
-+ return 0;
-+}
-+
-+/* Enable or disable promiscuous mode */
-+static void at76_work_set_promisc(struct work_struct *work)
-+{
-+ struct at76_priv *priv = container_of(work, struct at76_priv,
-+ work_set_promisc);
-+ int ret = 0;
-+
-+ mutex_lock(&priv->mtx);
-+
-+ priv->mib_buf.type = MIB_LOCAL;
-+ priv->mib_buf.size = 1;
-+ priv->mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
-+ priv->mib_buf.data.byte = priv->promisc ? 1 : 0;
-+
-+ ret = at76_set_mib(priv, &priv->mib_buf);
-+ if (ret < 0)
-+ printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+
-+ mutex_unlock(&priv->mtx);
-+}
-+
-+/* Submit Rx urb back to the device */
-+static void at76_work_submit_rx(struct work_struct *work)
-+{
-+ struct at76_priv *priv = container_of(work, struct at76_priv,
-+ work_submit_rx);
-+
-+ mutex_lock(&priv->mtx);
-+ at76_submit_rx_urb(priv);
-+ mutex_unlock(&priv->mtx);
-+}
-+
-+static void at76_rx_tasklet(unsigned long param)
-+{
-+ struct urb *urb = (struct urb *)param;
-+ struct at76_priv *priv = urb->context;
-+ struct at76_rx_buffer *buf;
-+ struct ieee80211_rx_status rx_status = { 0 };
-+
-+ if (priv->device_unplugged) {
-+ at76_dbg(DBG_DEVSTART, "device unplugged");
-+ if (urb)
-+ at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
-+ return;
-+ }
-+
-+ if (!priv->rx_skb || !priv->rx_skb->data)
-+ return;
-+
-+ buf = (struct at76_rx_buffer *)priv->rx_skb->data;
-+
-+ if (urb->status != 0) {
-+ if (urb->status != -ENOENT && urb->status != -ECONNRESET)
-+ at76_dbg(DBG_URB,
-+ "%s %s: - nonzero Rx bulk status received: %d",
-+ __func__, wiphy_name(priv->hw->wiphy),
-+ urb->status);
-+ return;
-+ }
-+
-+ at76_dbg(DBG_RX_ATMEL_HDR,
-+ "%s: rx frame: rate %d rssi %d noise %d link %d",
-+ wiphy_name(priv->hw->wiphy), buf->rx_rate, buf->rssi,
-+ buf->noise_level, buf->link_quality);
-+
-+ skb_pull(priv->rx_skb, AT76_RX_HDRLEN);
-+ skb_trim(priv->rx_skb, le16_to_cpu(buf->wlength));
-+ at76_dbg_dump(DBG_RX_DATA, priv->rx_skb->data,
-+ priv->rx_skb->len, "RX: len=%d", priv->rx_skb->len);
-+
-+ rx_status.ssi = buf->rssi;
-+ rx_status.flag |= RX_FLAG_DECRYPTED;
-+ rx_status.flag |= RX_FLAG_IV_STRIPPED;
-+
-+ at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
-+ priv->rx_skb->len, priv->rx_skb->data_len);
-+ ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status);
-+
-+ /* Use a new skb for the next receive */
-+ priv->rx_skb = NULL;
-+
-+ at76_submit_rx_urb(priv);
-+}
-+
-+/* Load firmware into kernel memory and parse it */
-+static struct fwentry *at76_load_firmware(struct usb_device *udev,
-+ enum board_type board_type)
-+{
-+ int ret;
-+ char *str;
-+ struct at76_fw_header *fwh;
-+ struct fwentry *fwe = &firmwares[board_type];
-+
-+ mutex_lock(&fw_mutex);
-+
-+ if (fwe->loaded) {
-+ at76_dbg(DBG_FW, "re-using previously loaded fw");
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
-+ ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
-+ if (ret < 0) {
-+ dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
-+ fwe->fwname);
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "you may need to download the firmware from "
-+ "http://developer.berlios.de/projects/at76c503a/\n");
-+ goto exit;
-+ }
-+
-+ at76_dbg(DBG_FW, "got it.");
-+ fwh = (struct at76_fw_header *)(fwe->fw->data);
-+
-+ if (fwe->fw->size <= sizeof(*fwh)) {
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "firmware is too short (0x%zx)\n", fwe->fw->size);
-+ goto exit;
-+ }
-+
-+ /* CRC currently not checked */
-+ fwe->board_type = le32_to_cpu(fwh->board_type);
-+ if (fwe->board_type != board_type) {
-+ dev_printk(KERN_ERR, &udev->dev,
-+ "board type mismatch, requested %u, got %u\n",
-+ board_type, fwe->board_type);
-+ goto exit;
-+ }
-+
-+ fwe->fw_version.major = fwh->major;
-+ fwe->fw_version.minor = fwh->minor;
-+ fwe->fw_version.patch = fwh->patch;
-+ fwe->fw_version.build = fwh->build;
-+
-+ str = (char *)fwh + le32_to_cpu(fwh->str_offset);
-+ fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
-+ fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
-+ fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
-+ fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
-+
-+ fwe->loaded = 1;
-+
-+ dev_printk(KERN_DEBUG, &udev->dev,
-+ "using firmware %s (version %d.%d.%d-%d)\n",
-+ fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
-+
-+ at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
-+ le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
-+ le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
-+ at76_dbg(DBG_DEVSTART, "firmware id %s", str);
-+
-+exit:
-+ mutex_unlock(&fw_mutex);
-+
-+ if (fwe->loaded)
-+ return fwe;
-+ else
-+ return NULL;
-+}
-+
-+static void at76_mac80211_tx_callback(struct urb *urb)
-+{
-+ struct at76_priv *priv = urb->context;
-+
-+ at76_dbg(DBG_MAC80211, "%s()", __func__);
-+
-+ switch (urb->status) {
-+ case 0:
-+ /* success */
-+ priv->tx_status.flags |= IEEE80211_TX_STATUS_ACK;
-+ break;
-+ case -ENOENT:
-+ case -ECONNRESET:
-+ /* fail, urb has been unlinked */
-+ /* FIXME: add error message */
-+ break;
-+ default:
-+ at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
-+ __func__, urb->status);
-+ break;
-+ }
-+
-+ priv->tx_status.excessive_retries = 0;
-+ priv->tx_status.retry_count = 0;
-+ priv->tx_status.ack_signal = 0;
-+
-+ ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb, &priv->tx_status);
-+
-+ memset(&priv->tx_status, 0, sizeof(priv->tx_status));
-+ priv->tx_skb = NULL;
-+
-+ ieee80211_start_queues(priv->hw);
-+}
-+
-+static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
-+ struct ieee80211_tx_control *control)
-+{
-+ struct at76_priv *priv = hw->priv;
-+ struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
-+ int padding, submit_len, ret;
-+
-+ at76_dbg(DBG_MAC80211, "%s()", __func__);
-+
-+ if (priv->tx_urb->status == -EINPROGRESS) {
-+ printk(KERN_ERR "%s: %s called while tx urb is pending\n",
-+ wiphy_name(priv->hw->wiphy), __func__);
-+ return NETDEV_TX_BUSY;
-+ }
-+
-+ ieee80211_stop_queues(hw);
-+
-+ at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
-+
-+ WARN_ON(priv->tx_skb != NULL);
-+
-+ priv->tx_skb = skb;
-+ memcpy(&priv->tx_status.control, control, sizeof(*control));
-+ padding = at76_calc_padding(skb->len);
-+ submit_len = AT76_TX_HDRLEN + skb->len + padding;
-+
-+ /* setup 'Atmel' header */
-+ memset(tx_buffer, 0, sizeof(*tx_buffer));
-+ tx_buffer->padding = padding;
-+ tx_buffer->wlength = cpu_to_le16(skb->len);
-+ tx_buffer->tx_rate = control->tx_rate->hw_value;
-+ memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
-+ memcpy(tx_buffer->packet, skb->data, skb->len);
-+
-+ at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr",
-+ wiphy_name(priv->hw->wiphy), le16_to_cpu(tx_buffer->wlength),
-+ tx_buffer->padding, tx_buffer->tx_rate);
-+
-+ /* send stuff */
-+ at76_dbg_dump(DBG_TX_DATA_CONTENT, tx_buffer, submit_len,
-+ "%s(): tx_buffer %d bytes:", __func__, submit_len);
-+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
-+ submit_len, at76_mac80211_tx_callback, priv);
-+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
-+ if (ret) {
-+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ if (ret == -EINVAL)
-+ printk(KERN_ERR
-+ "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
-+ wiphy_name(priv->hw->wiphy), priv->tx_urb,
-+ priv->tx_urb->hcpriv, priv->tx_urb->complete);
-+ }
-+
-+ return 0;
-+}
-+
-+static int at76_mac80211_start(struct ieee80211_hw *hw)
-+{
-+ struct at76_priv *priv = hw->priv;
-+ int ret;
-+
-+ at76_dbg(DBG_MAC80211, "%s()", __func__);
-+
-+ mutex_lock(&priv->mtx);
-+
-+ ret = at76_submit_rx_urb(priv);
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ goto error;
-+ }
-+
-+ at76_startup_device(priv);
-+
-+ at76_start_monitor(priv);
-+
-+error:
-+ mutex_unlock(&priv->mtx);
-+
-+ return 0;
-+}
-+
-+static void at76_mac80211_stop(struct ieee80211_hw *hw)
-+{
-+ struct at76_priv *priv = hw->priv;
-+
-+ at76_dbg(DBG_MAC80211, "%s()", __func__);
-+
-+ mutex_lock(&priv->mtx);
-+
-+ if (!priv->device_unplugged) {
-+ /* We are called by "ifconfig ethX down", not because the
-+ * device is not available anymore. */
-+ at76_set_radio(priv, 0);
-+
-+ /* We unlink rx_urb because at76_open() re-submits it.
-+ * If unplugged, at76_delete_device() takes care of it. */
-+ usb_kill_urb(priv->rx_urb);
-+ }
-+
-+ mutex_unlock(&priv->mtx);
-+}
-+
-+static int at76_add_interface(struct ieee80211_hw *hw,
-+ struct ieee80211_if_init_conf *conf)
-+{
-+ struct at76_priv *priv = hw->priv;
-+ int ret = 0;
-+
-+ at76_dbg(DBG_MAC80211, "%s()", __func__);
-+
-+ mutex_lock(&priv->mtx);
-+
-+ switch (conf->type) {
-+ case IEEE80211_IF_TYPE_STA:
-+ priv->iw_mode = IW_MODE_INFRA;
-+ break;
-+ default:
-+ ret = -EOPNOTSUPP;
-+ goto exit;
-+ }
-+
-+exit:
-+ mutex_unlock(&priv->mtx);
-+
-+ return ret;
-+}
-+
-+static void at76_remove_interface(struct ieee80211_hw *hw,
-+ struct ieee80211_if_init_conf *conf)
-+{
-+ at76_dbg(DBG_MAC80211, "%s()", __func__);
-+}
-+
-+static int at76_join(struct at76_priv *priv)
-+{
-+ struct at76_req_join join;
-+ int ret;
-+
-+ memset(&join, 0, sizeof(struct at76_req_join));
-+ memcpy(join.essid, priv->essid, priv->essid_size);
-+ join.essid_size = priv->essid_size;
-+ memcpy(join.bssid, priv->bssid, ETH_ALEN);
-+ join.bss_type = INFRASTRUCTURE_MODE;
-+ join.channel = priv->channel;
-+ join.timeout = cpu_to_le16(2000);
-+
-+ at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__);
-+ ret = at76_set_card_command(priv->udev, CMD_JOIN, &join,
-+ sizeof(struct at76_req_join));
-+
-+ if (ret < 0) {
-+ printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ return 0;
-+ }
-+
-+ ret = at76_wait_completion(priv, CMD_JOIN);
-+ at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
-+ if (ret != CMD_STATUS_COMPLETE) {
-+ printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
-+ wiphy_name(priv->hw->wiphy), ret);
-+ return 0;
-+ }
-+
-+ at76_set_pm_mode(priv);
-+
-+ return 0;
-+}
-+
-+static void at76_dwork_hw_scan(struct work_struct *work)
-+{
-+ struct at76_priv *priv = container_of(work, struct at76_priv,
-+ dwork_hw_scan.work);
-+ int ret;
-+
-+ mutex_lock(&priv->mtx);
-+
-+ ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
-+ at76_dbg(DBG_MAC80211, "%s: CMD_SCAN status 0x%02x", __func__, ret);
-+
-+ /* FIXME: add maximum time for scan to complete */
-+
-+ if (ret != CMD_STATUS_COMPLETE) {
-+ queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
-+ SCAN_POLL_INTERVAL);
-+ goto exit;
-+ }
-+
-+ ieee80211_scan_completed(priv->hw);
-+
-+ if (is_valid_ether_addr(priv->bssid))
-+ at76_join(priv);
-+
-+ ieee80211_start_queues(priv->hw);
-+
-+exit:
-+ mutex_unlock(&priv->mtx);
-+}
-+
-+static int at76_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
-+{
-+ struct at76_priv *priv = hw->priv;
-+ struct at76_req_scan scan;
-+ int ret;
-+
-+ at76_dbg(DBG_MAC80211, "%s():", __func__);
-+ at76_dbg_dump(DBG_MAC80211, ssid, len, "ssid %zd bytes:", len);
-+
-+ mutex_lock(&priv->mtx);
-+
-+ ieee80211_stop_queues(hw);
-+
-+ memset(&scan, 0, sizeof(struct at76_req_scan));
-+ memset(scan.bssid, 0xFF, ETH_ALEN);
-+ scan.scan_type = SCAN_TYPE_ACTIVE;
-+ if (priv->essid_size > 0) {
-+ memcpy(scan.essid, ssid, len);
-+ scan.essid_size = len;
-+ }
-+ scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
-+ scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
-+ scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
-+ scan.international_scan = 0;
-+
-+ at76_dbg(DBG_MAC80211, "%s: sending CMD_SCAN", __func__);
-+ ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
-+
-+ if (ret < 0) {
-+ err("CMD_SCAN failed: %d", ret);
-+ goto exit;
-+ }
-+
-+ queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
-+ SCAN_POLL_INTERVAL);
-+
-+exit:
-+ mutex_unlock(&priv->mtx);
-+
-+ return 0;
-+}
-+
-+static int at76_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
-+{
-+ struct at76_priv *priv = hw->priv;
-+
-+ at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d",
-+ __func__, conf->channel->hw_value, conf->radio_enabled);
-+ at76_dbg_dump(DBG_MAC80211, priv->essid, priv->essid_size, "ssid:");
-+ at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
-+
-+ mutex_lock(&priv->mtx);
-+
-+ priv->channel = conf->channel->hw_value;
-+
-+ if (is_valid_ether_addr(priv->bssid))
-+ at76_join(priv);
-+ else
-+ at76_start_monitor(priv);
-+
-+ mutex_unlock(&priv->mtx);
-+
-+ return 0;
-+}
-+
-+static int at76_config_interface(struct ieee80211_hw *hw,
-+ struct ieee80211_vif *vif,
-+ struct ieee80211_if_conf *conf)
-+{
-+ struct at76_priv *priv = hw->priv;
-+
-+ at76_dbg(DBG_MAC80211, "%s(): ssid_len=%zd", __func__, conf->ssid_len);
-+ at76_dbg_dump(DBG_MAC80211, conf->ssid, conf->ssid_len, "ssid:");
-+ at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
-+
-+ mutex_lock(&priv->mtx);
-+
-+ memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-+ memcpy(priv->essid, conf->ssid, conf->ssid_len);
-+ priv->essid_size = conf->ssid_len;
-+
-+ if (is_valid_ether_addr(priv->bssid))
-+ /* mac80211 is joining a bss */
-+ at76_join(priv);
-+
-+ mutex_unlock(&priv->mtx);
-+
-+ return 0;
-+}
-+
-+/* must be atomic */
-+static void at76_configure_filter(struct ieee80211_hw *hw,
-+ unsigned int changed_flags,
-+ unsigned int *total_flags, int mc_count,
-+ struct dev_addr_list *mc_list)
-+{
-+ struct at76_priv *priv = hw->priv;
-+ int flags;
-+
-+ at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x "
-+ "total_flags=0x%08x mc_count=%d",
-+ __func__, changed_flags, *total_flags, mc_count);
-+
-+ flags = changed_flags & AT76_SUPPORTED_FILTERS;
-+ *total_flags = AT76_SUPPORTED_FILTERS;
-+
-+ /* FIXME: access to priv->promisc should be protected with
-+ * priv->mtx, but it's impossible because this function needs to be
-+ * atomic */
-+
-+ if (flags && !priv->promisc) {
-+ /* mac80211 wants us to enable promiscuous mode */
-+ priv->promisc = 1;
-+ } else if (!flags && priv->promisc) {
-+ /* we need to disable promiscuous mode */
-+ priv->promisc = 0;
-+ } else
-+ return;
-+
-+ queue_work(hw->workqueue, &priv->work_set_promisc);
-+}
-+
-+static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-+ const u8 *local_address, const u8 *address,
-+ struct ieee80211_key_conf *key)
-+{
-+ struct at76_priv *priv = hw->priv;
-+
-+ int i;
-+
-+ at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
-+ "key->keylen %d",
-+ __func__, cmd, key->alg, key->keyidx, key->keylen);
-+
-+ if (key->alg != ALG_WEP)
-+ return -EOPNOTSUPP;
-+
-+ key->hw_key_idx = key->keyidx;
-+
-+ mutex_lock(&priv->mtx);
-+
-+ switch (cmd) {
-+ case SET_KEY:
-+ memcpy(priv->wep_keys[key->keyidx], key->key, key->keylen);
-+ priv->wep_keys_len[key->keyidx] = key->keylen;
-+
-+ /* FIXME: find out how to do this properly */
-+ priv->wep_key_id = key->keyidx;
-+
-+ break;
-+ case DISABLE_KEY:
-+ default:
-+ priv->wep_keys_len[key->keyidx] = 0;
-+ break;
-+ }
-+
-+ priv->wep_enabled = 0;
-+
-+ for (i = 0; i < WEP_KEYS; i++) {
-+ if (priv->wep_keys_len[i] != 0)
-+ priv->wep_enabled = 1;
-+ }
-+
-+ at76_startup_device(priv);
-+
-+ mutex_unlock(&priv->mtx);
-+
-+ return 0;
-+}
-+
-+static const struct ieee80211_ops at76_ops = {
-+ .tx = at76_mac80211_tx,
-+ .add_interface = at76_add_interface,
-+ .remove_interface = at76_remove_interface,
-+ .config = at76_config,
-+ .config_interface = at76_config_interface,
-+ .configure_filter = at76_configure_filter,
-+ .start = at76_mac80211_start,
-+ .stop = at76_mac80211_stop,
-+ .hw_scan = at76_hw_scan,
-+ .set_key = at76_set_key,
-+};
-+
-+/* Allocate network device and initialize private data */
-+static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
-+{
-+ struct ieee80211_hw *hw;
-+ struct at76_priv *priv;
-+
-+ hw = ieee80211_alloc_hw(sizeof(struct at76_priv), &at76_ops);
-+ if (!hw) {
-+ printk(KERN_ERR DRIVER_NAME ": could not register"
-+ " ieee80211_hw\n");
-+ return NULL;
-+ }
-+
-+ priv = hw->priv;
-+ priv->hw = hw;
-+
-+ priv->udev = udev;
-+
-+ mutex_init(&priv->mtx);
-+ INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
-+ INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
-+ INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
-+
-+ priv->rx_tasklet.func = at76_rx_tasklet;
-+ priv->rx_tasklet.data = 0;
-+
-+ priv->pm_mode = AT76_PM_OFF;
-+ priv->pm_period = 0;
-+
-+ /* unit us */
-+ priv->hw->channel_change_time = 100000;
-+
-+ return priv;
-+}
-+
-+static int at76_alloc_urbs(struct at76_priv *priv,
-+ struct usb_interface *interface)
-+{
-+ struct usb_endpoint_descriptor *endpoint, *ep_in, *ep_out;
-+ int i;
-+ int buffer_size;
-+ struct usb_host_interface *iface_desc;
-+
-+ at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
-+
-+ at76_dbg(DBG_URB, "%s: NumEndpoints %d ", __func__,
-+ interface->altsetting[0].desc.bNumEndpoints);
-+
-+ ep_in = NULL;
-+ ep_out = NULL;
-+ iface_desc = interface->cur_altsetting;
-+ for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
-+ endpoint = &iface_desc->endpoint[i].desc;
-+
-+ at76_dbg(DBG_URB, "%s: %d. endpoint: addr 0x%x attr 0x%x",
-+ __func__, i, endpoint->bEndpointAddress,
-+ endpoint->bmAttributes);
-+
-+ if (!ep_in && usb_endpoint_is_bulk_in(endpoint))
-+ ep_in = endpoint;
-+
-+ if (!ep_out && usb_endpoint_is_bulk_out(endpoint))
-+ ep_out = endpoint;
-+ }
-+
-+ if (!ep_in || !ep_out) {
-+ dev_printk(KERN_ERR, &interface->dev,
-+ "bulk endpoints missing\n");
-+ return -ENXIO;
-+ }
-+
-+ priv->rx_pipe = usb_rcvbulkpipe(priv->udev, ep_in->bEndpointAddress);
-+ priv->tx_pipe = usb_sndbulkpipe(priv->udev, ep_out->bEndpointAddress);
-+
-+ priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
-+ priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
-+ if (!priv->rx_urb || !priv->tx_urb) {
-+ dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n");
-+ return -ENOMEM;
-+ }
-+
-+ buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
-+ priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
-+ if (!priv->bulk_out_buffer) {
-+ dev_printk(KERN_ERR, &interface->dev,
-+ "cannot allocate output buffer\n");
-+ return -ENOMEM;
-+ }
-+
-+ at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
-+
-+ return 0;
-+}
-+
-+static struct ieee80211_rate at76_rates[] = {
-+ { .bitrate = 10, .hw_value = TX_RATE_1MBIT, },
-+ { .bitrate = 20, .hw_value = TX_RATE_2MBIT, },
-+ { .bitrate = 55, .hw_value = TX_RATE_5_5MBIT, },
-+ { .bitrate = 110, .hw_value = TX_RATE_11MBIT, },
-+};
-+
-+static struct ieee80211_channel at76_channels[] = {
-+ { .center_freq = 2412, .hw_value = 1 },
-+ { .center_freq = 2417, .hw_value = 2 },
-+ { .center_freq = 2422, .hw_value = 3 },
-+ { .center_freq = 2427, .hw_value = 4 },
-+ { .center_freq = 2432, .hw_value = 5 },
-+ { .center_freq = 2437, .hw_value = 6 },
-+ { .center_freq = 2442, .hw_value = 7 },
-+ { .center_freq = 2447, .hw_value = 8 },
-+ { .center_freq = 2452, .hw_value = 9 },
-+ { .center_freq = 2457, .hw_value = 10 },
-+ { .center_freq = 2462, .hw_value = 11 },
-+ { .center_freq = 2467, .hw_value = 12 },
-+ { .center_freq = 2472, .hw_value = 13 },
-+ { .center_freq = 2484, .hw_value = 14 }
-+};
-+
-+static struct ieee80211_supported_band at76_supported_band = {
-+ .channels = at76_channels,
-+ .n_channels = ARRAY_SIZE(at76_channels),
-+ .bitrates = at76_rates,
-+ .n_bitrates = ARRAY_SIZE(at76_rates),
-+};
-+
-+/* Register network device and initialize the hardware */
-+static int at76_init_new_device(struct at76_priv *priv,
-+ struct usb_interface *interface)
-+{
-+ int ret;
-+
-+ /* set up the endpoint information */
-+ /* check out the endpoints */
-+
-+ at76_dbg(DBG_DEVSTART, "USB interface: %d endpoints",
-+ interface->cur_altsetting->desc.bNumEndpoints);
-+
-+ ret = at76_alloc_urbs(priv, interface);
-+ if (ret < 0)
-+ goto exit;
-+
-+ /* MAC address */
-+ ret = at76_get_hw_config(priv);
-+ if (ret < 0) {
-+ dev_printk(KERN_ERR, &interface->dev,
-+ "cannot get MAC address\n");
-+ goto exit;
-+ }
-+
-+ priv->domain = at76_get_reg_domain(priv->regulatory_domain);
-+
-+ priv->channel = DEF_CHANNEL;
-+ priv->iw_mode = IW_MODE_INFRA;
-+ priv->rts_threshold = DEF_RTS_THRESHOLD;
-+ priv->frag_threshold = DEF_FRAG_THRESHOLD;
-+ priv->short_retry_limit = DEF_SHORT_RETRY_LIMIT;
-+ priv->txrate = TX_RATE_AUTO;
-+ priv->preamble_type = PREAMBLE_TYPE_LONG;
-+ priv->beacon_period = 100;
-+ priv->auth_mode = WLAN_AUTH_OPEN;
-+ priv->scan_min_time = DEF_SCAN_MIN_TIME;
-+ priv->scan_max_time = DEF_SCAN_MAX_TIME;
-+ priv->scan_mode = SCAN_TYPE_ACTIVE;
-+
-+ /* mac80211 initialisation */
-+ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band;
-+ priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS;
-+
-+ SET_IEEE80211_DEV(priv->hw, &interface->dev);
-+ SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
-+
-+ ret = ieee80211_register_hw(priv->hw);
-+ if (ret) {
-+ printk(KERN_ERR "cannot register mac80211 hw (status %d)!\n",
-+ ret);
-+ goto exit;
-+ }
-+
-+ priv->mac80211_registered = 1;
-+
-+ printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
-+ wiphy_name(priv->hw->wiphy),
-+ interface->dev.bus_id, mac2str(priv->mac_addr),
-+ priv->fw_version.major, priv->fw_version.minor,
-+ priv->fw_version.patch, priv->fw_version.build);
-+ printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n",
-+ wiphy_name(priv->hw->wiphy),
-+ priv->regulatory_domain, priv->domain->name);
-+
-+exit:
-+ return ret;
-+}
-+
-+static void at76_delete_device(struct at76_priv *priv)
-+{
-+ at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
-+
-+ /* The device is gone, don't bother turning it off */
-+ priv->device_unplugged = 1;
-+
-+ if (priv->mac80211_registered)
-+ ieee80211_unregister_hw(priv->hw);
-+
-+ /* assuming we used keventd, it must quiesce too */
-+ flush_scheduled_work();
-+
-+ kfree(priv->bulk_out_buffer);
-+
-+ if (priv->tx_urb) {
-+ usb_kill_urb(priv->tx_urb);
-+ usb_free_urb(priv->tx_urb);
-+ }
-+ if (priv->rx_urb) {
-+ usb_kill_urb(priv->rx_urb);
-+ usb_free_urb(priv->rx_urb);
-+ }
-+
-+ at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
-+
-+ if (priv->rx_skb)
-+ kfree_skb(priv->rx_skb);
-+
-+ usb_put_dev(priv->udev);
-+
-+ at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw",
-+ __func__);
-+ ieee80211_free_hw(priv->hw);
-+
-+ at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
-+}
-+
-+static int at76_probe(struct usb_interface *interface,
-+ const struct usb_device_id *id)
-+{
-+ int ret;
-+ struct at76_priv *priv;
-+ struct fwentry *fwe;
-+ struct usb_device *udev;
-+ int op_mode;
-+ int need_ext_fw = 0;
-+ struct mib_fw_version fwv;
-+ int board_type = (int)id->driver_info;
-+
-+ udev = usb_get_dev(interface_to_usbdev(interface));
-+
-+ /* Load firmware into kernel memory */
-+ fwe = at76_load_firmware(udev, board_type);
-+ if (!fwe) {
-+ ret = -ENOENT;
-+ goto error;
-+ }
-+
-+ op_mode = at76_get_op_mode(udev);
-+
-+ at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
-+
-+ /* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
-+ we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
-+
-+ if (op_mode == OPMODE_HW_CONFIG_MODE) {
-+ dev_printk(KERN_ERR, &interface->dev,
-+ "cannot handle a device in HW_CONFIG_MODE\n");
-+ ret = -EBUSY;
-+ goto error;
-+ }
-+
-+ if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
-+ && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
-+ /* download internal firmware part */
-+ dev_printk(KERN_DEBUG, &interface->dev,
-+ "downloading internal firmware\n");
-+ ret = at76_load_internal_fw(udev, fwe);
-+ if (ret < 0) {
-+ dev_printk(KERN_ERR, &interface->dev,
-+ "error %d downloading internal firmware\n",
-+ ret);
-+ goto error;
-+ }
-+ usb_put_dev(udev);
-+ return ret;
-+ }
-+
-+ /* Internal firmware already inside the device. Get firmware
-+ * version to test if external firmware is loaded.
-+ * This works only for newer firmware, e.g. the Intersil 0.90.x
-+ * says "control timeout on ep0in" and subsequent
-+ * at76_get_op_mode() fail too :-( */
-+
-+ /* if version >= 0.100.x.y or device with built-in flash we can
-+ * query the device for the fw version */
-+ if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100)
-+ || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
-+ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
-+ if (ret < 0 || (fwv.major | fwv.minor) == 0)
-+ need_ext_fw = 1;
-+ } else
-+ /* No way to check firmware version, reload to be sure */
-+ need_ext_fw = 1;
-+
-+ if (need_ext_fw) {
-+ dev_printk(KERN_DEBUG, &interface->dev,
-+ "downloading external firmware\n");
-+
-+ ret = at76_load_external_fw(udev, fwe);
-+ if (ret)
-+ goto error;
-+
-+ /* Re-check firmware version */
-+ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
-+ if (ret < 0) {
-+ dev_printk(KERN_ERR, &interface->dev,
-+ "error %d getting firmware version\n", ret);
-+ goto error;
-+ }
-+ }
-+
-+ priv = at76_alloc_new_device(udev);
-+ if (!priv) {
-+ ret = -ENOMEM;
-+ goto error;
-+ }
-+
-+ usb_set_intfdata(interface, priv);
-+
-+ memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
-+ priv->board_type = board_type;
-+
-+ ret = at76_init_new_device(priv, interface);
-+ if (ret < 0)
-+ at76_delete_device(priv);
-+
-+ return ret;
-+
-+error:
-+ usb_put_dev(udev);
-+ return ret;
-+}
-+
-+static void at76_disconnect(struct usb_interface *interface)
-+{
-+ struct at76_priv *priv;
-+
-+ priv = usb_get_intfdata(interface);
-+ usb_set_intfdata(interface, NULL);
-+
-+ /* Disconnect after loading internal firmware */
-+ if (!priv)
-+ return;
-+
-+ printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy));
-+ at76_delete_device(priv);
-+ dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
-+}
-+
-+/* Structure for registering this driver with the USB subsystem */
-+static struct usb_driver at76_driver = {
-+ .name = DRIVER_NAME,
-+ .probe = at76_probe,
-+ .disconnect = at76_disconnect,
-+ .id_table = dev_table,
-+};
-+
-+static int __init at76_mod_init(void)
-+{
-+ int result;
-+
-+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n");
-+
-+ mutex_init(&fw_mutex);
-+
-+ /* register this driver with the USB subsystem */
-+ result = usb_register(&at76_driver);
-+ if (result < 0)
-+ printk(KERN_ERR DRIVER_NAME
-+ ": usb_register failed (status %d)\n", result);
-+
-+ led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
-+ return result;
-+}
-+
-+static void __exit at76_mod_exit(void)
-+{
-+ int i;
-+
-+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
-+ usb_deregister(&at76_driver);
-+ for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
-+ if (firmwares[i].fw)
-+ release_firmware(firmwares[i].fw);
-+ }
-+ led_trigger_unregister_simple(ledtrig_tx);
-+}
-+
-+module_param_named(debug, at76_debug, int, 0600);
-+MODULE_PARM_DESC(debug, "Debugging level");
-+
-+module_init(at76_mod_init);
-+module_exit(at76_mod_exit);
-+
-+MODULE_AUTHOR("Oliver Kurth <oku@masqmail.cx>");
-+MODULE_AUTHOR("Joerg Albert <joerg.albert@gmx.de>");
-+MODULE_AUTHOR("Alex <alex@foogod.com>");
-+MODULE_AUTHOR("Nick Jones");
-+MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
-+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
-+MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>");
-+MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>");
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+MODULE_LICENSE("GPL");
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/at76_usb.h linux-2.6.25/drivers/net/wireless/at76_usb.h
---- linux-2.6.25.old/drivers/net/wireless/at76_usb.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.25/drivers/net/wireless/at76_usb.h 2008-04-19 16:23:26.000000000 +0200
-@@ -0,0 +1,464 @@
-+/*
-+ * Copyright (c) 2002,2003 Oliver Kurth
-+ * (c) 2003,2004 Joerg Albert <joerg.albert@gmx.de>
-+ * (c) 2007 Guido Guenther <agx@sigxcpu.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 driver was based on information from the Sourceforge driver
-+ * released and maintained by Atmel:
-+ *
-+ * http://sourceforge.net/projects/atmelwlandriver/
-+ *
-+ * Although the code was completely re-written,
-+ * it would have been impossible without Atmel's decision to
-+ * release an Open Source driver (unfortunately the firmware was
-+ * kept binary only). Thanks for that decision to Atmel!
-+ */
-+
-+#ifndef _AT76_USB_H
-+#define _AT76_USB_H
-+
-+/* Board types */
-+enum board_type {
-+ BOARD_503_ISL3861 = 1,
-+ BOARD_503_ISL3863 = 2,
-+ BOARD_503 = 3,
-+ BOARD_503_ACC = 4,
-+ BOARD_505 = 5,
-+ BOARD_505_2958 = 6,
-+ BOARD_505A = 7,
-+ BOARD_505AMX = 8
-+};
-+
-+#define CMD_STATUS_IDLE 0x00
-+#define CMD_STATUS_COMPLETE 0x01
-+#define CMD_STATUS_UNKNOWN 0x02
-+#define CMD_STATUS_INVALID_PARAMETER 0x03
-+#define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
-+#define CMD_STATUS_TIME_OUT 0x07
-+#define CMD_STATUS_IN_PROGRESS 0x08
-+#define CMD_STATUS_HOST_FAILURE 0xff
-+#define CMD_STATUS_SCAN_FAILED 0xf0
-+
-+/* answers to get op mode */
-+#define OPMODE_NONE 0x00
-+#define OPMODE_NORMAL_NIC_WITH_FLASH 0x01
-+#define OPMODE_HW_CONFIG_MODE 0x02
-+#define OPMODE_DFU_MODE_WITH_FLASH 0x03
-+#define OPMODE_NORMAL_NIC_WITHOUT_FLASH 0x04
-+
-+#define CMD_SET_MIB 0x01
-+#define CMD_GET_MIB 0x02
-+#define CMD_SCAN 0x03
-+#define CMD_JOIN 0x04
-+#define CMD_START_IBSS 0x05
-+#define CMD_RADIO_ON 0x06
-+#define CMD_RADIO_OFF 0x07
-+#define CMD_STARTUP 0x0B
-+
-+#define MIB_LOCAL 0x01
-+#define MIB_MAC_ADDR 0x02
-+#define MIB_MAC 0x03
-+#define MIB_MAC_MGMT 0x05
-+#define MIB_MAC_WEP 0x06
-+#define MIB_PHY 0x07
-+#define MIB_FW_VERSION 0x08
-+#define MIB_MDOMAIN 0x09
-+
-+#define ADHOC_MODE 1
-+#define INFRASTRUCTURE_MODE 2
-+
-+/* values for struct mib_local, field preamble_type */
-+#define PREAMBLE_TYPE_LONG 0
-+#define PREAMBLE_TYPE_SHORT 1
-+#define PREAMBLE_TYPE_AUTO 2
-+
-+/* values for tx_rate */
-+#define TX_RATE_1MBIT 0
-+#define TX_RATE_2MBIT 1
-+#define TX_RATE_5_5MBIT 2
-+#define TX_RATE_11MBIT 3
-+#define TX_RATE_AUTO 4
-+
-+/* power management modes */
-+#define AT76_PM_OFF 1
-+#define AT76_PM_ON 2
-+#define AT76_PM_SMART 3
-+
-+struct hwcfg_r505 {
-+ u8 cr39_values[14];
-+ u8 reserved1[14];
-+ u8 bb_cr[14];
-+ u8 pidvid[4];
-+ u8 mac_addr[ETH_ALEN];
-+ u8 regulatory_domain;
-+ u8 reserved2[14];
-+ u8 cr15_values[14];
-+ u8 reserved3[3];
-+} __attribute__((packed));
-+
-+struct hwcfg_rfmd {
-+ u8 cr20_values[14];
-+ u8 cr21_values[14];
-+ u8 bb_cr[14];
-+ u8 pidvid[4];
-+ u8 mac_addr[ETH_ALEN];
-+ u8 regulatory_domain;
-+ u8 low_power_values[14];
-+ u8 normal_power_values[14];
-+ u8 reserved1[3];
-+} __attribute__((packed));
-+
-+struct hwcfg_intersil {
-+ u8 mac_addr[ETH_ALEN];
-+ u8 cr31_values[14];
-+ u8 cr58_values[14];
-+ u8 pidvid[4];
-+ u8 regulatory_domain;
-+ u8 reserved[1];
-+} __attribute__((packed));
-+
-+union at76_hwcfg {
-+ struct hwcfg_intersil i;
-+ struct hwcfg_rfmd r3;
-+ struct hwcfg_r505 r5;
-+};
-+
-+#define WEP_SMALL_KEY_LEN (40 / 8)
-+#define WEP_LARGE_KEY_LEN (104 / 8)
-+#define WEP_KEYS (4)
-+
-+struct at76_card_config {
-+ u8 exclude_unencrypted;
-+ u8 promiscuous_mode;
-+ u8 short_retry_limit;
-+ u8 encryption_type;
-+ __le16 rts_threshold;
-+ __le16 fragmentation_threshold; /* 256..2346 */
-+ u8 basic_rate_set[4];
-+ u8 auto_rate_fallback; /* 0,1 */
-+ u8 channel;
-+ u8 privacy_invoked;
-+ u8 wep_default_key_id; /* 0..3 */
-+ u8 current_ssid[32];
-+ u8 wep_default_key_value[4][WEP_LARGE_KEY_LEN];
-+ u8 ssid_len;
-+ u8 short_preamble;
-+ __le16 beacon_period;
-+} __attribute__((packed));
-+
-+struct at76_command {
-+ u8 cmd;
-+ u8 reserved;
-+ __le16 size;
-+ u8 data[0];
-+} __attribute__((packed));
-+
-+/* Length of Atmel-specific Rx header before 802.11 frame */
-+#define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet)
-+
-+struct at76_rx_buffer {
-+ __le16 wlength;
-+ u8 rx_rate;
-+ u8 newbss;
-+ u8 fragmentation;
-+ u8 rssi;
-+ u8 link_quality;
-+ u8 noise_level;
-+ __le32 rx_time;
-+ u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
-+} __attribute__((packed));
-+
-+/* Length of Atmel-specific Tx header before 802.11 frame */
-+#define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet)
-+
-+struct at76_tx_buffer {
-+ __le16 wlength;
-+ u8 tx_rate;
-+ u8 padding;
-+ u8 reserved[4];
-+ u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
-+} __attribute__((packed));
-+
-+/* defines for scan_type below */
-+#define SCAN_TYPE_ACTIVE 0
-+#define SCAN_TYPE_PASSIVE 1
-+
-+struct at76_req_scan {
-+ u8 bssid[ETH_ALEN];
-+ u8 essid[32];
-+ u8 scan_type;
-+ u8 channel;
-+ __le16 probe_delay;
-+ __le16 min_channel_time;
-+ __le16 max_channel_time;
-+ u8 essid_size;
-+ u8 international_scan;
-+} __attribute__((packed));
-+
-+struct at76_req_ibss {
-+ u8 bssid[ETH_ALEN];
-+ u8 essid[32];
-+ u8 bss_type;
-+ u8 channel;
-+ u8 essid_size;
-+ u8 reserved[3];
-+} __attribute__((packed));
-+
-+struct at76_req_join {
-+ u8 bssid[ETH_ALEN];
-+ u8 essid[32];
-+ u8 bss_type;
-+ u8 channel;
-+ __le16 timeout;
-+ u8 essid_size;
-+ u8 reserved;
-+} __attribute__((packed));
-+
-+struct set_mib_buffer {
-+ u8 type;
-+ u8 size;
-+ u8 index;
-+ u8 reserved;
-+ union {
-+ u8 byte;
-+ __le16 word;
-+ u8 addr[ETH_ALEN];
-+ } data;
-+} __attribute__((packed));
-+
-+struct mib_local {
-+ u16 reserved0;
-+ u8 beacon_enable;
-+ u8 txautorate_fallback;
-+ u8 reserved1;
-+ u8 ssid_size;
-+ u8 promiscuous_mode;
-+ u16 reserved2;
-+ u8 preamble_type;
-+ u16 reserved3;
-+} __attribute__((packed));
-+
-+struct mib_mac_addr {
-+ u8 mac_addr[ETH_ALEN];
-+ u8 res[2]; /* ??? */
-+ u8 group_addr[4][ETH_ALEN];
-+ u8 group_addr_status[4];
-+} __attribute__((packed));
-+
-+struct mib_mac {
-+ __le32 max_tx_msdu_lifetime;
-+ __le32 max_rx_lifetime;
-+ __le16 frag_threshold;
-+ __le16 rts_threshold;
-+ __le16 cwmin;
-+ __le16 cwmax;
-+ u8 short_retry_time;
-+ u8 long_retry_time;
-+ u8 scan_type; /* active or passive */
-+ u8 scan_channel;
-+ __le16 probe_delay; /* delay before ProbeReq in active scan, RO */
-+ __le16 min_channel_time;
-+ __le16 max_channel_time;
-+ __le16 listen_interval;
-+ u8 desired_ssid[32];
-+ u8 desired_bssid[ETH_ALEN];
-+ u8 desired_bsstype; /* ad-hoc or infrastructure */
-+ u8 reserved2;
-+} __attribute__((packed));
-+
-+struct mib_mac_mgmt {
-+ __le16 beacon_period;
-+ __le16 CFP_max_duration;
-+ __le16 medium_occupancy_limit;
-+ __le16 station_id; /* assoc id */
-+ __le16 ATIM_window;
-+ u8 CFP_mode;
-+ u8 privacy_option_implemented;
-+ u8 DTIM_period;
-+ u8 CFP_period;
-+ u8 current_bssid[ETH_ALEN];
-+ u8 current_essid[32];
-+ u8 current_bss_type;
-+ u8 power_mgmt_mode;
-+ /* rfmd and 505 */
-+ u8 ibss_change;
-+ u8 res;
-+ u8 multi_domain_capability_implemented;
-+ u8 multi_domain_capability_enabled;
-+ u8 country_string[3];
-+ u8 reserved[3];
-+} __attribute__((packed));
-+
-+struct mib_mac_wep {
-+ u8 privacy_invoked; /* 0 disable encr., 1 enable encr */
-+ u8 wep_default_key_id;
-+ u8 wep_key_mapping_len;
-+ u8 exclude_unencrypted;
-+ __le32 wep_icv_error_count;
-+ __le32 wep_excluded_count;
-+ u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN];
-+ u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
-+} __attribute__((packed));
-+
-+struct mib_phy {
-+ __le32 ed_threshold;
-+
-+ __le16 slot_time;
-+ __le16 sifs_time;
-+ __le16 preamble_length;
-+ __le16 plcp_header_length;
-+ __le16 mpdu_max_length;
-+ __le16 cca_mode_supported;
-+
-+ u8 operation_rate_set[4];
-+ u8 channel_id;
-+ u8 current_cca_mode;
-+ u8 phy_type;
-+ u8 current_reg_domain;
-+} __attribute__((packed));
-+
-+struct mib_fw_version {
-+ u8 major;
-+ u8 minor;
-+ u8 patch;
-+ u8 build;
-+} __attribute__((packed));
-+
-+struct mib_mdomain {
-+ u8 tx_powerlevel[14];
-+ u8 channel_list[14]; /* 0 for invalid channels */
-+} __attribute__((packed));
-+
-+struct at76_fw_header {
-+ __le32 crc; /* CRC32 of the whole image */
-+ __le32 board_type; /* firmware compatibility code */
-+ u8 build; /* firmware build number */
-+ u8 patch; /* firmware patch level */
-+ u8 minor; /* firmware minor version */
-+ u8 major; /* firmware major version */
-+ __le32 str_offset; /* offset of the copyright string */
-+ __le32 int_fw_offset; /* internal firmware image offset */
-+ __le32 int_fw_len; /* internal firmware image length */
-+ __le32 ext_fw_offset; /* external firmware image offset */
-+ __le32 ext_fw_len; /* external firmware image length */
-+} __attribute__((packed));
-+
-+/* a description of a regulatory domain and the allowed channels */
-+struct reg_domain {
-+ u16 code;
-+ char const *name;
-+ u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
-+};
-+
-+/* Data for one loaded firmware file */
-+struct fwentry {
-+ const char *const fwname;
-+ const struct firmware *fw;
-+ int extfw_size;
-+ int intfw_size;
-+ /* pointer to loaded firmware, no need to free */
-+ u8 *extfw; /* external firmware, extfw_size bytes long */
-+ u8 *intfw; /* internal firmware, intfw_size bytes long */
-+ enum board_type board_type; /* board type */
-+ struct mib_fw_version fw_version;
-+ int loaded; /* Loaded and parsed successfully */
-+};
-+
-+struct at76_priv {
-+ struct usb_device *udev; /* USB device pointer */
-+
-+ struct sk_buff *rx_skb; /* skbuff for receiving data */
-+ struct sk_buff *tx_skb; /* skbuff for transmitting data */
-+ void *bulk_out_buffer; /* buffer for sending data */
-+
-+ struct urb *tx_urb; /* URB for sending data */
-+ struct urb *rx_urb; /* URB for receiving data */
-+
-+ unsigned int tx_pipe; /* bulk out pipe */
-+ unsigned int rx_pipe; /* bulk in pipe */
-+
-+ struct mutex mtx; /* locks this structure */
-+
-+ /* work queues */
-+ struct work_struct work_set_promisc;
-+ struct work_struct work_submit_rx;
-+ struct delayed_work dwork_hw_scan;
-+
-+ struct tasklet_struct rx_tasklet;
-+
-+ /* the WEP stuff */
-+ int wep_enabled; /* 1 if WEP is enabled */
-+ int wep_key_id; /* key id to be used */
-+ u8 wep_keys[WEP_KEYS][WEP_LARGE_KEY_LEN]; /* WEP keys */
-+ u8 wep_keys_len[WEP_KEYS]; /* length of WEP keys */
-+
-+ int channel;
-+ int iw_mode;
-+ u8 bssid[ETH_ALEN];
-+ u8 essid[IW_ESSID_MAX_SIZE];
-+ int essid_size;
-+ int radio_on;
-+ int promisc;
-+
-+ int preamble_type; /* 0 - long, 1 - short, 2 - auto */
-+ int auth_mode; /* authentication type: 0 open, 1 shared key */
-+ int txrate; /* 0,1,2,3 = 1,2,5.5,11 Mbps, 4 is auto */
-+ int frag_threshold; /* threshold for fragmentation of tx packets */
-+ int rts_threshold; /* threshold for RTS mechanism */
-+ int short_retry_limit;
-+
-+ int scan_min_time; /* scan min channel time */
-+ int scan_max_time; /* scan max channel time */
-+ int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
-+ int scan_need_any; /* if set, need to scan for any ESSID */
-+
-+ u16 assoc_id; /* current association ID, if associated */
-+
-+ u8 pm_mode; /* power management mode */
-+ u32 pm_period; /* power management period in microseconds */
-+
-+ struct reg_domain const *domain; /* reg domain description */
-+
-+ /* These fields contain HW config provided by the device (not all of
-+ * these fields are used by all board types) */
-+ u8 mac_addr[ETH_ALEN];
-+ u8 regulatory_domain;
-+
-+ struct at76_card_config card_config;
-+
-+ enum board_type board_type;
-+ struct mib_fw_version fw_version;
-+
-+ unsigned int device_unplugged:1;
-+ unsigned int netdev_registered:1;
-+ struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
-+
-+ int beacon_period; /* period of mgmt beacons, Kus */
-+
-+ struct ieee80211_hw *hw;
-+ struct ieee80211_tx_status tx_status;
-+ int mac80211_registered;
-+};
-+
-+#define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS
-+
-+#define SCAN_POLL_INTERVAL (HZ / 4)
-+
-+#define CMD_COMPLETION_TIMEOUT (5 * HZ)
-+
-+#define DEF_RTS_THRESHOLD 1536
-+#define DEF_FRAG_THRESHOLD 1536
-+#define DEF_SHORT_RETRY_LIMIT 8
-+#define DEF_CHANNEL 10
-+#define DEF_SCAN_MIN_TIME 10
-+#define DEF_SCAN_MAX_TIME 120
-+
-+/* the max padding size for tx in bytes (see calc_padding) */
-+#define MAX_PADDING_SIZE 53
-+
-+#endif /* _AT76_USB_H */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/ath5k.h linux-2.6.25/drivers/net/wireless/ath5k/ath5k.h
---- linux-2.6.25.old/drivers/net/wireless/ath5k/ath5k.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/ath5k.h 2008-04-19 13:54:59.000000000 +0200
-@@ -30,7 +30,6 @@
- #include <net/mac80211.h>
-
- #include "hw.h"
--#include "regdom.h"
-
- /* PCI IDs */
- #define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */
-@@ -141,7 +140,9 @@
- AR5K_RF5110 = 0,
- AR5K_RF5111 = 1,
- AR5K_RF5112 = 2,
-- AR5K_RF5413 = 3,
-+ AR5K_RF2413 = 3,
-+ AR5K_RF5413 = 4,
-+ AR5K_RF2425 = 5,
- };
-
- /*
-@@ -169,12 +170,15 @@
- #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_AR2413 0x78
-+#define AR5K_SREV_VER_AR2414 0x79
-+#define AR5K_SREV_VER_AR2424 0xa0 /* PCI-E */
-+#define AR5K_SREV_VER_AR5424 0xa3 /* PCI-E */
- #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_AR5416 0xc0 /* PCI-E */
-+#define AR5K_SREV_VER_AR5418 0xca /* PCI-E */
-+#define AR5K_SREV_VER_AR2425 0xe2 /* PCI-E */
-
- #define AR5K_SREV_RAD_5110 0x00
- #define AR5K_SREV_RAD_5111 0x10
-@@ -184,8 +188,9 @@
- #define AR5K_SREV_RAD_5112A 0x35
- #define AR5K_SREV_RAD_2112 0x40
- #define AR5K_SREV_RAD_2112A 0x45
-+#define AR5K_SREV_RAD_SC0 0x56 /* Found on 2413/2414 */
- #define AR5K_SREV_RAD_SC1 0x63 /* Found on 5413/5414 */
--#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424/5424 */
-+#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424-5/5424 */
- #define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */
-
- /* IEEE defs */
-@@ -251,26 +256,31 @@
- */
- #define MODULATION_TURBO 0x00000080
-
--enum ath5k_vendor_mode {
-- MODE_ATHEROS_TURBO = NUM_IEEE80211_MODES+1,
-- MODE_ATHEROS_TURBOG
-+enum ath5k_driver_mode {
-+ AR5K_MODE_11A = 0,
-+ AR5K_MODE_11A_TURBO = 1,
-+ AR5K_MODE_11B = 2,
-+ AR5K_MODE_11G = 3,
-+ AR5K_MODE_11G_TURBO = 4,
-+ AR5K_MODE_XR = 0,
-+ AR5K_MODE_MAX = 5
- };
-
--/* Number of supported mac80211 enum ieee80211_phymode modes by this driver */
--#define NUM_DRIVER_MODES 3
--
- /* adding this flag to rate_code enables short preamble, see ar5212_reg.h */
- #define AR5K_SET_SHORT_PREAMBLE 0x04
-
--#define HAS_SHPREAMBLE(_ix) (rt->rates[_ix].modulation == IEEE80211_RATE_CCK_2)
--#define SHPREAMBLE_FLAG(_ix) (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0)
-+#define HAS_SHPREAMBLE(_ix) \
-+ (rt->rates[_ix].modulation == IEEE80211_RATE_SHORT_PREAMBLE)
-+#define SHPREAMBLE_FLAG(_ix) \
-+ (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0)
-+
-
- /****************\
- TX DEFINITIONS
- \****************/
-
- /*
-- * Tx Descriptor
-+ * TX Status
- */
- struct ath5k_tx_status {
- u16 ts_seqnum;
-@@ -418,7 +428,7 @@
- \****************/
-
- /*
-- * Rx Descriptor
-+ * RX Status
- */
- struct ath5k_rx_status {
- u16 rs_datalen;
-@@ -440,16 +450,6 @@
- #define AR5K_RXKEYIX_INVALID ((u8) - 1)
- #define AR5K_TXKEYIX_INVALID ((u32) - 1)
-
--struct ath5k_mib_stats {
-- u32 ackrcv_bad;
-- u32 rts_bad;
-- u32 rts_good;
-- u32 fcs_bad;
-- u32 beacons;
--};
--
--
--
-
- /**************************\
- BEACON TIMERS DEFINITIONS
-@@ -492,29 +492,23 @@
- #define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10)
-
-
--
- /********************\
- COMMON DEFINITIONS
- \********************/
-
- /*
-- * Atheros descriptor
-+ * Atheros hardware descriptor
-+ * This is read and written to by the hardware
- */
- struct ath5k_desc {
-- u32 ds_link;
-- u32 ds_data;
-- u32 ds_ctl0;
-- u32 ds_ctl1;
-- u32 ds_hw[4];
-+ u32 ds_link; /* physical address of the next descriptor */
-+ u32 ds_data; /* physical address of data buffer (skb) */
-
- union {
-- struct ath5k_rx_status rx;
-- struct ath5k_tx_status tx;
-- } ds_us;
--
--#define ds_rxstat ds_us.rx
--#define ds_txstat ds_us.tx
--
-+ struct ath5k_hw_5210_tx_desc ds_tx5210;
-+ struct ath5k_hw_5212_tx_desc ds_tx5212;
-+ struct ath5k_hw_all_rx_desc ds_rx;
-+ } ud;
- } __packed;
-
- #define AR5K_RXDESC_INTREQ 0x0020
-@@ -560,8 +554,8 @@
- * Used internaly in OpenHAL (ar5211.c/ar5212.c
- * for reset_tx_queue). Also see struct struct ieee80211_channel.
- */
--#define IS_CHAN_XR(_c) ((_c.val & CHANNEL_XR) != 0)
--#define IS_CHAN_B(_c) ((_c.val & CHANNEL_B) != 0)
-+#define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0)
-+#define IS_CHAN_B(_c) ((_c.hw_value & CHANNEL_B) != 0)
-
- /*
- * The following structure will be used to map 2GHz channels to
-@@ -584,7 +578,7 @@
-
- /**
- * struct ath5k_rate - rate structure
-- * @valid: is this a valid rate for the current mode
-+ * @valid: is this a valid rate for rate control (remove)
- * @modulation: respective mac80211 modulation
- * @rate_kbps: rate in kbit/s
- * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on
-@@ -643,47 +637,48 @@
-
- /*
- * Rate tables...
-+ * TODO: CLEAN THIS !!!
- */
- #define AR5K_RATES_11A { 8, { \
- 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \
- 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \
- 255, 255, 255, 255, 255, 255, 255, 255 }, { \
-- { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 0 }, \
-- { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 0 }, \
-- { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 2 }, \
-- { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 2 }, \
-- { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 4 }, \
-- { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 4 }, \
-- { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 4 }, \
-- { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 4 } } \
-+ { 1, 0, 6000, 11, 140, 0 }, \
-+ { 1, 0, 9000, 15, 18, 0 }, \
-+ { 1, 0, 12000, 10, 152, 2 }, \
-+ { 1, 0, 18000, 14, 36, 2 }, \
-+ { 1, 0, 24000, 9, 176, 4 }, \
-+ { 1, 0, 36000, 13, 72, 4 }, \
-+ { 1, 0, 48000, 8, 96, 4 }, \
-+ { 1, 0, 54000, 12, 108, 4 } } \
- }
-
- #define AR5K_RATES_11B { 4, { \
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \
- 3, 2, 1, 0, 255, 255, 255, 255 }, { \
-- { 1, IEEE80211_RATE_CCK, 1000, 27, 130, 0 }, \
-- { 1, IEEE80211_RATE_CCK_2, 2000, 26, 132, 1 }, \
-- { 1, IEEE80211_RATE_CCK_2, 5500, 25, 139, 1 }, \
-- { 1, IEEE80211_RATE_CCK_2, 11000, 24, 150, 1 } } \
-+ { 1, 0, 1000, 27, 130, 0 }, \
-+ { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 132, 1 }, \
-+ { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 139, 1 }, \
-+ { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 150, 1 } } \
- }
-
- #define AR5K_RATES_11G { 12, { \
- 255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4, \
- 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \
- 3, 2, 1, 0, 255, 255, 255, 255 }, { \
-- { 1, IEEE80211_RATE_CCK, 1000, 27, 2, 0 }, \
-- { 1, IEEE80211_RATE_CCK_2, 2000, 26, 4, 1 }, \
-- { 1, IEEE80211_RATE_CCK_2, 5500, 25, 11, 1 }, \
-- { 1, IEEE80211_RATE_CCK_2, 11000, 24, 22, 1 }, \
-- { 0, IEEE80211_RATE_OFDM, 6000, 11, 12, 4 }, \
-- { 0, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \
-- { 1, IEEE80211_RATE_OFDM, 12000, 10, 24, 6 }, \
-- { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \
-- { 1, IEEE80211_RATE_OFDM, 24000, 9, 48, 8 }, \
-- { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \
-- { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \
-- { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \
-+ { 1, 0, 1000, 27, 2, 0 }, \
-+ { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 4, 1 }, \
-+ { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 11, 1 }, \
-+ { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 22, 1 }, \
-+ { 0, 0, 6000, 11, 12, 4 }, \
-+ { 0, 0, 9000, 15, 18, 4 }, \
-+ { 1, 0, 12000, 10, 24, 6 }, \
-+ { 1, 0, 18000, 14, 36, 6 }, \
-+ { 1, 0, 24000, 9, 48, 8 }, \
-+ { 1, 0, 36000, 13, 72, 8 }, \
-+ { 1, 0, 48000, 8, 96, 8 }, \
-+ { 1, 0, 54000, 12, 108, 8 } } \
- }
-
- #define AR5K_RATES_TURBO { 8, { \
-@@ -708,14 +703,14 @@
- { 1, MODULATION_XR, 1000, 2, 139, 1 }, \
- { 1, MODULATION_XR, 2000, 6, 150, 2 }, \
- { 1, MODULATION_XR, 3000, 1, 150, 3 }, \
-- { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 4 }, \
-- { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \
-- { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 6 }, \
-- { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \
-- { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 8 }, \
-- { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \
-- { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \
-- { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \
-+ { 1, 0, 6000, 11, 140, 4 }, \
-+ { 1, 0, 9000, 15, 18, 4 }, \
-+ { 1, 0, 12000, 10, 152, 6 }, \
-+ { 1, 0, 18000, 14, 36, 6 }, \
-+ { 1, 0, 24000, 9, 176, 8 }, \
-+ { 1, 0, 36000, 13, 72, 8 }, \
-+ { 1, 0, 48000, 8, 96, 8 }, \
-+ { 1, 0, 54000, 12, 108, 8 } } \
- }
-
- /*
-@@ -890,12 +885,14 @@
- AR5K_CAP_RFSILENT = 20, /* Supports RFsilent */
- };
-
-+
-+/* XXX: we *may* move cap_range stuff to struct wiphy */
- struct ath5k_capabilities {
- /*
- * Supported PHY modes
- * (ie. CHANNEL_A, CHANNEL_B, ...)
- */
-- DECLARE_BITMAP(cap_mode, NUM_DRIVER_MODES);
-+ DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX);
-
- /*
- * Frequency range (without regulation restrictions)
-@@ -908,14 +905,6 @@
- } cap_range;
-
- /*
-- * Active regulation domain settings
-- */
-- struct {
-- enum ath5k_regdom reg_current;
-- enum ath5k_regdom reg_hw;
-- } cap_regdomain;
--
-- /*
- * Values stored in the EEPROM (some of them...)
- */
- struct ath5k_eeprom_info cap_eeprom;
-@@ -963,6 +952,7 @@
- u16 ah_phy_revision;
- u16 ah_radio_5ghz_revision;
- u16 ah_radio_2ghz_revision;
-+ u32 ah_phy_spending;
-
- enum ath5k_version ah_version;
- enum ath5k_radio ah_radio;
-@@ -1038,8 +1028,10 @@
- int (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *,
- unsigned int, unsigned int, unsigned int, unsigned int,
- unsigned int, unsigned int);
-- int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *);
-- int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *);
-+ int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-+ struct ath5k_tx_status *);
-+ int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-+ struct ath5k_rx_status *);
- };
-
- /*
-@@ -1070,6 +1062,7 @@
- extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
- extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
- extern enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask);
-+extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats);
- /* EEPROM access functions */
- extern int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain);
- /* Protocol Control Unit Functions */
-@@ -1098,7 +1091,6 @@
- extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
- extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
- #endif
--extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ath5k_mib_stats *statistics);
- /* ACK bit rate */
- void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
- /* ACK/CTS Timeouts */
-@@ -1129,8 +1121,6 @@
- extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
- extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
- extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
--/* Regulatory Domain/Channels Setup */
--extern u16 ath5k_get_regdomain(struct ath5k_hw *ah);
- /* Misc functions */
- extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
-
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/base.c linux-2.6.25/drivers/net/wireless/ath5k/base.c
---- linux-2.6.25.old/drivers/net/wireless/ath5k/base.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/base.c 2008-04-19 13:54:59.000000000 +0200
-@@ -80,7 +80,7 @@
- MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
- MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
- MODULE_LICENSE("Dual BSD/GPL");
--MODULE_VERSION("0.1.1 (EXPERIMENTAL)");
-+MODULE_VERSION("0.5.0 (EXPERIMENTAL)");
-
-
- /* Known PCI ids */
-@@ -118,12 +118,15 @@
- { "5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212 },
- { "5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213 },
- { "5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A },
-+ { "2413", AR5K_VERSION_VER, AR5K_SREV_VER_AR2413 },
-+ { "2414", AR5K_VERSION_VER, AR5K_SREV_VER_AR2414 },
- { "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 },
-@@ -132,6 +135,7 @@
- { "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_SC0 },
- { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1 },
- { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2 },
- { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 },
-@@ -240,6 +244,8 @@
- static void ath5k_setcurmode(struct ath5k_softc *sc,
- unsigned int mode);
- static void ath5k_mode_setup(struct ath5k_softc *sc);
-+static void ath5k_set_total_hw_rates(struct ath5k_softc *sc);
-+
- /* Descriptor setup */
- static int ath5k_desc_alloc(struct ath5k_softc *sc,
- struct pci_dev *pdev);
-@@ -278,7 +284,8 @@
- static void ath5k_rx_stop(struct ath5k_softc *sc);
- static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
- struct ath5k_desc *ds,
-- struct sk_buff *skb);
-+ struct sk_buff *skb,
-+ struct ath5k_rx_status *rs);
- static void ath5k_tasklet_rx(unsigned long data);
- /* Tx handling */
- static void ath5k_tx_processq(struct ath5k_softc *sc,
-@@ -511,34 +518,45 @@
- sc->ah->ah_mac_srev,
- sc->ah->ah_phy_revision);
-
-- if(!sc->ah->ah_single_chip){
-+ if (!sc->ah->ah_single_chip) {
- /* Single chip radio (!RF5111) */
-- if(sc->ah->ah_radio_5ghz_revision && !sc->ah->ah_radio_2ghz_revision) {
-+ if (sc->ah->ah_radio_5ghz_revision &&
-+ !sc->ah->ah_radio_2ghz_revision) {
- /* No 5GHz support -> report 2GHz radio */
-- if(!test_bit(MODE_IEEE80211A, sc->ah->ah_capabilities.cap_mode)){
-+ if (!test_bit(AR5K_MODE_11A,
-+ sc->ah->ah_capabilities.cap_mode)) {
- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
-- ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision),
-+ ath5k_chip_name(AR5K_VERSION_RAD,
-+ sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
-- /* No 2GHz support (5110 and some 5Ghz only cards) -> report 5Ghz radio */
-- } else if(!test_bit(MODE_IEEE80211B, sc->ah->ah_capabilities.cap_mode)){
-+ /* No 2GHz support (5110 and some
-+ * 5Ghz only cards) -> report 5Ghz radio */
-+ } else if (!test_bit(AR5K_MODE_11B,
-+ sc->ah->ah_capabilities.cap_mode)) {
- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
-- ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision),
-+ ath5k_chip_name(AR5K_VERSION_RAD,
-+ sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- /* Multiband radio */
- } else {
- ATH5K_INFO(sc, "RF%s multiband radio found"
- " (0x%x)\n",
-- ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision),
-+ ath5k_chip_name(AR5K_VERSION_RAD,
-+ sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- }
- }
-- /* Multi chip radio (RF5111 - RF2111) -> report both 2GHz/5GHz radios */
-- else if(sc->ah->ah_radio_5ghz_revision && sc->ah->ah_radio_2ghz_revision){
-+ /* Multi chip radio (RF5111 - RF2111) ->
-+ * report both 2GHz/5GHz radios */
-+ else if (sc->ah->ah_radio_5ghz_revision &&
-+ sc->ah->ah_radio_2ghz_revision){
- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
-- ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision),
-+ ath5k_chip_name(AR5K_VERSION_RAD,
-+ sc->ah->ah_radio_5ghz_revision),
- sc->ah->ah_radio_5ghz_revision);
- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
-- ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_2ghz_revision),
-+ ath5k_chip_name(AR5K_VERSION_RAD,
-+ sc->ah->ah_radio_2ghz_revision),
- sc->ah->ah_radio_2ghz_revision);
- }
- }
-@@ -693,11 +711,14 @@
- goto err;
- }
-
-+ /* Set *_rates so we can map hw rate index */
-+ ath5k_set_total_hw_rates(sc);
-+
- /* NB: setup here so ath5k_rate_update is happy */
-- if (test_bit(MODE_IEEE80211A, ah->ah_modes))
-- ath5k_setcurmode(sc, MODE_IEEE80211A);
-+ if (test_bit(AR5K_MODE_11A, ah->ah_modes))
-+ ath5k_setcurmode(sc, AR5K_MODE_11A);
- else
-- ath5k_setcurmode(sc, MODE_IEEE80211B);
-+ ath5k_setcurmode(sc, AR5K_MODE_11B);
-
- /*
- * Allocate tx+rx descriptors and populate the lists.
-@@ -837,12 +858,9 @@
- return 0;
-
- for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) {
-- if (!rt->rates[i].valid)
-- continue;
-- rates->rate = rt->rates[i].rate_kbps / 100;
-- rates->val = rt->rates[i].rate_code;
-- rates->flags = rt->rates[i].modulation;
-- rates++;
-+ rates[count].bitrate = rt->rates[i].rate_kbps / 100;
-+ rates[count].hw_value = rt->rates[i].rate_code;
-+ rates[count].flags = rt->rates[i].modulation;
- count++;
- max--;
- }
-@@ -856,43 +874,22 @@
- unsigned int mode,
- unsigned int max)
- {
-- static const struct { unsigned int mode, mask, chan; } map[] = {
-- [MODE_IEEE80211A] = { CHANNEL_OFDM, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_A },
-- [MODE_ATHEROS_TURBO] = { CHANNEL_OFDM|CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_T },
-- [MODE_IEEE80211B] = { CHANNEL_CCK, CHANNEL_CCK, CHANNEL_B },
-- [MODE_IEEE80211G] = { CHANNEL_OFDM, CHANNEL_OFDM, CHANNEL_G },
-- [MODE_ATHEROS_TURBOG] = { CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_TG },
-- };
-- static const struct ath5k_regchannel chans_2ghz[] =
-- IEEE80211_CHANNELS_2GHZ;
-- static const struct ath5k_regchannel chans_5ghz[] =
-- IEEE80211_CHANNELS_5GHZ;
-- const struct ath5k_regchannel *chans;
-- enum ath5k_regdom dmn;
-- unsigned int i, count, size, chfreq, all, f, ch;
-+ unsigned int i, count, size, chfreq, freq, ch;
-
- if (!test_bit(mode, ah->ah_modes))
- return 0;
-
-- all = ah->ah_regdomain == DMN_DEFAULT || CHAN_DEBUG == 1;
--
- switch (mode) {
-- case MODE_IEEE80211A:
-- case MODE_ATHEROS_TURBO:
-+ case AR5K_MODE_11A:
-+ case AR5K_MODE_11A_TURBO:
- /* 1..220, but 2GHz frequencies are filtered by check_channel */
-- size = all ? 220 : ARRAY_SIZE(chans_5ghz);
-- chans = chans_5ghz;
-- dmn = ath5k_regdom2flag(ah->ah_regdomain,
-- IEEE80211_CHANNELS_5GHZ_MIN);
-+ size = 220 ;
- chfreq = CHANNEL_5GHZ;
- break;
-- case MODE_IEEE80211B:
-- case MODE_IEEE80211G:
-- case MODE_ATHEROS_TURBOG:
-- size = all ? 26 : ARRAY_SIZE(chans_2ghz);
-- chans = chans_2ghz;
-- dmn = ath5k_regdom2flag(ah->ah_regdomain,
-- IEEE80211_CHANNELS_2GHZ_MIN);
-+ case AR5K_MODE_11B:
-+ case AR5K_MODE_11G:
-+ case AR5K_MODE_11G_TURBO:
-+ size = 26;
- chfreq = CHANNEL_2GHZ;
- break;
- default:
-@@ -901,25 +898,31 @@
- }
-
- for (i = 0, count = 0; i < size && max > 0; i++) {
-- ch = all ? i + 1 : chans[i].chan;
-- f = ath5k_ieee2mhz(ch);
-- /* Check if channel is supported by the chipset */
-- if (!ath5k_channel_ok(ah, f, chfreq))
-- continue;
-+ ch = i + 1 ;
-+ freq = ath5k_ieee2mhz(ch);
-
-- /* Match regulation domain */
-- if (!all && !(IEEE80211_DMN(chans[i].domain) &
-- IEEE80211_DMN(dmn)))
-+ /* Check if channel is supported by the chipset */
-+ if (!ath5k_channel_ok(ah, freq, chfreq))
- continue;
-
-- if (!all && (chans[i].mode & map[mode].mask) != map[mode].mode)
-- continue;
-+ /* Write channel info and increment counter */
-+ channels[count].center_freq = freq;
-+ channels[count].band = (chfreq == CHANNEL_2GHZ) ?
-+ IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
-+ switch (mode) {
-+ case AR5K_MODE_11A:
-+ case AR5K_MODE_11G:
-+ channels[count].hw_value = chfreq | CHANNEL_OFDM;
-+ break;
-+ case AR5K_MODE_11A_TURBO:
-+ case AR5K_MODE_11G_TURBO:
-+ channels[count].hw_value = chfreq |
-+ CHANNEL_OFDM | CHANNEL_TURBO;
-+ break;
-+ case AR5K_MODE_11B:
-+ channels[count].hw_value = CHANNEL_B;
-+ }
-
-- /* Write channel and increment counter */
-- channels->chan = ch;
-- channels->freq = f;
-- channels->val = map[mode].chan;
-- channels++;
- count++;
- max--;
- }
-@@ -927,95 +930,78 @@
- return count;
- }
-
--/* Only tries to register modes our EEPROM says it can support */
--#define REGISTER_MODE(m) do { \
-- ret = ath5k_register_mode(hw, m); \
-- if (ret) \
-- return ret; \
--} while (0) \
--
--static inline int
--ath5k_register_mode(struct ieee80211_hw *hw, u8 m)
-+static int
-+ath5k_getchannels(struct ieee80211_hw *hw)
- {
- struct ath5k_softc *sc = hw->priv;
-- struct ieee80211_hw_mode *modes = sc->modes;
-- unsigned int i;
-- int ret;
-+ struct ath5k_hw *ah = sc->ah;
-+ struct ieee80211_supported_band *sbands = sc->sbands;
-+ const struct ath5k_rate_table *hw_rates;
-+ unsigned int max_r, max_c, count_r, count_c;
-+ int mode2g = AR5K_MODE_11G;
-
-- if (!test_bit(m, sc->ah->ah_capabilities.cap_mode))
-- return 0;
-+ BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS);
-
-- for (i = 0; i < NUM_DRIVER_MODES; i++) {
-- if (modes[i].mode != m || !modes[i].num_channels)
-- continue;
-- ret = ieee80211_register_hwmode(hw, &modes[i]);
-- if (ret) {
-- ATH5K_ERR(sc, "can't register hwmode %u\n", m);
-- return ret;
-+ max_r = ARRAY_SIZE(sc->rates);
-+ max_c = ARRAY_SIZE(sc->channels);
-+ count_r = count_c = 0;
-+
-+ /* 2GHz band */
-+ if (!test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) {
-+ mode2g = AR5K_MODE_11B;
-+ if (!test_bit(AR5K_MODE_11B,
-+ sc->ah->ah_capabilities.cap_mode))
-+ mode2g = -1;
- }
-- return 0;
-+
-+ if (mode2g > 0) {
-+ struct ieee80211_supported_band *sband =
-+ &sbands[IEEE80211_BAND_2GHZ];
-+
-+ sband->bitrates = sc->rates;
-+ sband->channels = sc->channels;
-+
-+ sband->band = IEEE80211_BAND_2GHZ;
-+ sband->n_channels = ath5k_copy_channels(ah, sband->channels,
-+ mode2g, max_c);
-+
-+ hw_rates = ath5k_hw_get_rate_table(ah, mode2g);
-+ sband->n_bitrates = ath5k_copy_rates(sband->bitrates,
-+ hw_rates, max_r);
-+
-+ count_c = sband->n_channels;
-+ count_r = sband->n_bitrates;
-+
-+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
-+
-+ max_r -= count_r;
-+ max_c -= count_c;
-+
- }
-- BUG();
--}
-
--static int
--ath5k_getchannels(struct ieee80211_hw *hw)
--{
-- struct ath5k_softc *sc = hw->priv;
-- struct ath5k_hw *ah = sc->ah;
-- struct ieee80211_hw_mode *modes = sc->modes;
-- unsigned int i, max_r, max_c;
-- int ret;
-+ /* 5GHz band */
-
-- BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 3);
-+ if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) {
-+ struct ieee80211_supported_band *sband =
-+ &sbands[IEEE80211_BAND_5GHZ];
-
-- /* The order here does not matter */
-- modes[0].mode = MODE_IEEE80211G;
-- modes[1].mode = MODE_IEEE80211B;
-- modes[2].mode = MODE_IEEE80211A;
-+ sband->bitrates = &sc->rates[count_r];
-+ sband->channels = &sc->channels[count_c];
-
-- max_r = ARRAY_SIZE(sc->rates);
-- max_c = ARRAY_SIZE(sc->channels);
-+ sband->band = IEEE80211_BAND_5GHZ;
-+ sband->n_channels = ath5k_copy_channels(ah, sband->channels,
-+ AR5K_MODE_11A, max_c);
-
-- for (i = 0; i < NUM_DRIVER_MODES; i++) {
-- struct ieee80211_hw_mode *mode = &modes[i];
-- const struct ath5k_rate_table *hw_rates;
-+ hw_rates = ath5k_hw_get_rate_table(ah, AR5K_MODE_11A);
-+ sband->n_bitrates = ath5k_copy_rates(sband->bitrates,
-+ hw_rates, max_r);
-
-- if (i == 0) {
-- modes[0].rates = sc->rates;
-- modes->channels = sc->channels;
-- } else {
-- struct ieee80211_hw_mode *prev_mode = &modes[i-1];
-- int prev_num_r = prev_mode->num_rates;
-- int prev_num_c = prev_mode->num_channels;
-- mode->rates = &prev_mode->rates[prev_num_r];
-- mode->channels = &prev_mode->channels[prev_num_c];
-- }
--
-- hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
-- mode->num_rates = ath5k_copy_rates(mode->rates, hw_rates,
-- max_r);
-- mode->num_channels = ath5k_copy_channels(ah, mode->channels,
-- mode->mode, max_c);
-- max_r -= mode->num_rates;
-- max_c -= mode->num_channels;
-- }
--
-- /* We try to register all modes this driver supports. We don't bother
-- * with MODE_IEEE80211B for AR5212 as MODE_IEEE80211G already accounts
-- * for that as per mac80211. Then, REGISTER_MODE() will will actually
-- * check the eeprom reading for more reliable capability information.
-- * Order matters here as per mac80211's latest preference. This will
-- * all hopefullly soon go away. */
--
-- REGISTER_MODE(MODE_IEEE80211G);
-- if (ah->ah_version != AR5K_AR5212)
-- REGISTER_MODE(MODE_IEEE80211B);
-- REGISTER_MODE(MODE_IEEE80211A);
-+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
-+ }
-
-- ath5k_debug_dump_modes(sc, modes);
-+ ath5k_debug_dump_bands(sc);
-
-- return ret;
-+ return 0;
- }
-
- /*
-@@ -1030,11 +1016,15 @@
- struct ath5k_hw *ah = sc->ah;
- int ret;
-
-- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "%u (%u MHz) -> %u (%u MHz)\n",
-- sc->curchan->chan, sc->curchan->freq,
-- chan->chan, chan->freq);
-+ ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
-+ sc->curchan->center_freq, chan->center_freq);
-+
-+ if (chan->center_freq != sc->curchan->center_freq ||
-+ chan->hw_value != sc->curchan->hw_value) {
-+
-+ sc->curchan = chan;
-+ sc->curband = &sc->sbands[chan->band];
-
-- if (chan->freq != sc->curchan->freq || chan->val != sc->curchan->val) {
- /*
- * To switch channels clear any pending DMA operations;
- * wait long enough for the RX fifo to drain, reset the
-@@ -1044,13 +1034,13 @@
- ath5k_hw_set_intr(ah, 0); /* disable interrupts */
- ath5k_txq_cleanup(sc); /* clear pending tx frames */
- ath5k_rx_stop(sc); /* turn off frame recv */
-- ret = ath5k_hw_reset(ah, sc->opmode, chan, true);
-+ ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
- if (ret) {
-- ATH5K_ERR(sc, "%s: unable to reset channel %u "
-- "(%u Mhz)\n", __func__, chan->chan, chan->freq);
-+ ATH5K_ERR(sc, "%s: unable to reset channel "
-+ "(%u Mhz)\n", __func__, chan->center_freq);
- return ret;
- }
-- sc->curchan = chan;
-+
- ath5k_hw_set_txpower_limit(sc->ah, 0);
-
- /*
-@@ -1081,6 +1071,9 @@
- return 0;
- }
-
-+/*
-+ * TODO: CLEAN THIS !!!
-+ */
- static void
- ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
- {
-@@ -1121,10 +1114,6 @@
- continue;
- }
- sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD;
-- if (SHPREAMBLE_FLAG(ix) || rt->rates[ix].modulation ==
-- IEEE80211_RATE_OFDM)
-- sc->hwmap[i].txflags |=
-- IEEE80211_RADIOTAP_F_SHORTPRE;
- /* receive frames include FCS */
- sc->hwmap[i].rxflags = sc->hwmap[i].txflags |
- IEEE80211_RADIOTAP_F_FCS;
-@@ -1142,6 +1131,12 @@
- }
-
- sc->curmode = mode;
-+
-+ if (mode == AR5K_MODE_11A) {
-+ sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ];
-+ } else {
-+ sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ];
-+ }
- }
-
- static void
-@@ -1164,6 +1159,72 @@
- ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
- }
-
-+/*
-+ * Match the hw provided rate index (through descriptors)
-+ * to an index for sc->curband->bitrates, so it can be used
-+ * by the stack.
-+ *
-+ * This one is a little bit tricky but i think i'm right
-+ * about this...
-+ *
-+ * We have 4 rate tables in the following order:
-+ * XR (4 rates)
-+ * 802.11a (8 rates)
-+ * 802.11b (4 rates)
-+ * 802.11g (12 rates)
-+ * that make the hw rate table.
-+ *
-+ * Lets take a 5211 for example that supports a and b modes only.
-+ * First comes the 802.11a table and then 802.11b (total 12 rates).
-+ * When hw returns eg. 11 it points to the last 802.11b rate (11Mbit),
-+ * if it returns 2 it points to the second 802.11a rate etc.
-+ *
-+ * Same goes for 5212 who has xr/a/b/g support (total 28 rates).
-+ * First comes the XR table, then 802.11a, 802.11b and 802.11g.
-+ * When hw returns eg. 27 it points to the last 802.11g rate (54Mbits) etc
-+ */
-+static void
-+ath5k_set_total_hw_rates(struct ath5k_softc *sc) {
-+
-+ struct ath5k_hw *ah = sc->ah;
-+
-+ if (test_bit(AR5K_MODE_11A, ah->ah_modes))
-+ sc->a_rates = 8;
-+
-+ if (test_bit(AR5K_MODE_11B, ah->ah_modes))
-+ sc->b_rates = 4;
-+
-+ if (test_bit(AR5K_MODE_11G, ah->ah_modes))
-+ sc->g_rates = 12;
-+
-+ /* XXX: Need to see what what happens when
-+ xr disable bits in eeprom are set */
-+ if (ah->ah_version >= AR5K_AR5212)
-+ sc->xr_rates = 4;
-+
-+}
-+
-+static inline int
-+ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) {
-+
-+ int mac80211_rix;
-+
-+ if(sc->curband->band == IEEE80211_BAND_2GHZ) {
-+ /* We setup a g ratetable for both b/g modes */
-+ mac80211_rix =
-+ hw_rix - sc->b_rates - sc->a_rates - sc->xr_rates;
-+ } else {
-+ mac80211_rix = hw_rix - sc->xr_rates;
-+ }
-+
-+ /* Something went wrong, fallback to basic rate for this band */
-+ if ((mac80211_rix >= sc->curband->n_bitrates) ||
-+ (mac80211_rix <= 0 ))
-+ mac80211_rix = 1;
-+
-+ return mac80211_rix;
-+}
-+
-
-
-
-@@ -1268,7 +1329,8 @@
-
- ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
- ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
-- (ctl->power_level * 2), ctl->tx_rate, ctl->retry_limit, keyidx, 0, flags, 0, 0);
-+ (sc->power_level * 2), ctl->tx_rate->hw_value,
-+ ctl->retry_limit, keyidx, 0, flags, 0, 0);
- if (ret)
- goto err_unmap;
-
-@@ -1503,8 +1565,7 @@
- */
- spin_lock_bh(&txq->lock);
- list_for_each_entry_safe(bf, bf0, &txq->q, list) {
-- ath5k_debug_printtxbuf(sc, bf, !sc->ah->ah_proc_tx_desc(sc->ah,
-- bf->desc));
-+ ath5k_debug_printtxbuf(sc, bf);
-
- ath5k_txbuf_free(sc, bf);
-
-@@ -1629,20 +1690,20 @@
-
- static unsigned int
- ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
-- struct sk_buff *skb)
-+ struct sk_buff *skb, struct ath5k_rx_status *rs)
- {
- struct ieee80211_hdr *hdr = (void *)skb->data;
- unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb);
-
-- if (!(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) &&
-- ds->ds_rxstat.rs_keyix != AR5K_RXKEYIX_INVALID)
-+ if (!(rs->rs_status & AR5K_RXERR_DECRYPT) &&
-+ rs->rs_keyix != AR5K_RXKEYIX_INVALID)
- return RX_FLAG_DECRYPTED;
-
- /* Apparently when a default key is used to decrypt the packet
- the hw does not set the index used to decrypt. In such cases
- get the index from the packet. */
- if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) &&
-- !(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) &&
-+ !(rs->rs_status & AR5K_RXERR_DECRYPT) &&
- skb->len >= hlen + 4) {
- keyix = skb->data[hlen + 3] >> 6;
-
-@@ -1655,28 +1716,62 @@
-
-
- static void
--ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb)
-+ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
-+ struct ieee80211_rx_status *rxs)
- {
-+ u64 tsf, bc_tstamp;
- u32 hw_tu;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-
-- if ((mgmt->frame_control & IEEE80211_FCTL_FTYPE) ==
-+ if ((le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_FTYPE) ==
- IEEE80211_FTYPE_MGMT &&
-- (mgmt->frame_control & IEEE80211_FCTL_STYPE) ==
-+ (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) ==
- IEEE80211_STYPE_BEACON &&
-- mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS &&
-+ le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
- memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
- /*
-- * Received an IBSS beacon with the same BSSID. Hardware might
-- * have updated the TSF, check if we need to update timers.
-+ * Received an IBSS beacon with the same BSSID. Hardware *must*
-+ * have updated the local TSF. We have to work around various
-+ * hardware bugs, though...
-+ */
-+ tsf = ath5k_hw_get_tsf64(sc->ah);
-+ bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp);
-+ hw_tu = TSF_TO_TU(tsf);
-+
-+ ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-+ "beacon %llx mactime %llx (diff %lld) tsf now %llx\n",
-+ (unsigned long long)bc_tstamp,
-+ (unsigned long long)rxs->mactime,
-+ (unsigned long long)(rxs->mactime - bc_tstamp),
-+ (unsigned long long)tsf);
-+
-+ /*
-+ * Sometimes the HW will give us a wrong tstamp in the rx
-+ * status, causing the timestamp extension to go wrong.
-+ * (This seems to happen especially with beacon frames bigger
-+ * than 78 byte (incl. FCS))
-+ * But we know that the receive timestamp must be later than the
-+ * timestamp of the beacon since HW must have synced to that.
-+ *
-+ * NOTE: here we assume mactime to be after the frame was
-+ * received, not like mac80211 which defines it at the start.
- */
-- hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah));
-- if (hw_tu >= sc->nexttbtt) {
-- ath5k_beacon_update_timers(sc,
-- mgmt->u.beacon.timestamp);
-+ if (bc_tstamp > rxs->mactime) {
- ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-- "detected HW merge from received beacon\n");
-+ "fixing mactime from %llx to %llx\n",
-+ (unsigned long long)rxs->mactime,
-+ (unsigned long long)tsf);
-+ rxs->mactime = tsf;
- }
-+
-+ /*
-+ * Local TSF might have moved higher than our beacon timers,
-+ * in that case we have to update them to continue sending
-+ * beacons. This also takes care of synchronizing beacon sending
-+ * times with other stations.
-+ */
-+ if (hw_tu >= sc->nexttbtt)
-+ ath5k_beacon_update_timers(sc, bc_tstamp);
- }
- }
-
-@@ -1685,12 +1780,11 @@
- ath5k_tasklet_rx(unsigned long data)
- {
- struct ieee80211_rx_status rxs = {};
-+ struct ath5k_rx_status rs = {};
- struct sk_buff *skb;
- struct ath5k_softc *sc = (void *)data;
- struct ath5k_buf *bf;
- struct ath5k_desc *ds;
-- u16 len;
-- u8 stat;
- int ret;
- int hdrlen;
- int pad;
-@@ -1713,7 +1807,7 @@
- if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */
- break;
-
-- ret = sc->ah->ah_proc_rx_desc(sc->ah, ds);
-+ ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
- if (unlikely(ret == -EINPROGRESS))
- break;
- else if (unlikely(ret)) {
-@@ -1722,16 +1816,15 @@
- return;
- }
-
-- if (unlikely(ds->ds_rxstat.rs_more)) {
-+ if (unlikely(rs.rs_more)) {
- ATH5K_WARN(sc, "unsupported jumbo\n");
- goto next;
- }
-
-- stat = ds->ds_rxstat.rs_status;
-- if (unlikely(stat)) {
-- if (stat & AR5K_RXERR_PHY)
-+ if (unlikely(rs.rs_status)) {
-+ if (rs.rs_status & AR5K_RXERR_PHY)
- goto next;
-- if (stat & AR5K_RXERR_DECRYPT) {
-+ if (rs.rs_status & AR5K_RXERR_DECRYPT) {
- /*
- * Decrypt error. If the error occurred
- * because there was no hardware key, then
-@@ -1742,30 +1835,29 @@
- *
- * XXX do key cache faulting
- */
-- if (ds->ds_rxstat.rs_keyix ==
-- AR5K_RXKEYIX_INVALID &&
-- !(stat & AR5K_RXERR_CRC))
-+ if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
-+ !(rs.rs_status & AR5K_RXERR_CRC))
- goto accept;
- }
-- if (stat & AR5K_RXERR_MIC) {
-+ if (rs.rs_status & AR5K_RXERR_MIC) {
- rxs.flag |= RX_FLAG_MMIC_ERROR;
- goto accept;
- }
-
- /* let crypto-error packets fall through in MNTR */
-- if ((stat & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
-+ if ((rs.rs_status &
-+ ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
- sc->opmode != IEEE80211_IF_TYPE_MNTR)
- goto next;
- }
- accept:
-- len = ds->ds_rxstat.rs_datalen;
-- pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, len,
-- PCI_DMA_FROMDEVICE);
-+ pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr,
-+ rs.rs_datalen, PCI_DMA_FROMDEVICE);
- pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
- PCI_DMA_FROMDEVICE);
- bf->skb = NULL;
-
-- skb_put(skb, len);
-+ skb_put(skb, rs.rs_datalen);
-
- /*
- * the hardware adds a padding to 4 byte boundaries between
-@@ -1787,13 +1879,23 @@
- * 15bit only. that means TSF extension has to be done within
- * 32768usec (about 32ms). it might be necessary to move this to
- * the interrupt handler, like it is done in madwifi.
-+ *
-+ * Unfortunately we don't know when the hardware takes the rx
-+ * timestamp (beginning of phy frame, data frame, end of rx?).
-+ * The only thing we know is that it is hardware specific...
-+ * On AR5213 it seems the rx timestamp is at the end of the
-+ * frame, but i'm not sure.
-+ *
-+ * NOTE: mac80211 defines mactime at the beginning of the first
-+ * data symbol. Since we don't have any time references it's
-+ * impossible to comply to that. This affects IBSS merge only
-+ * right now, so it's not too bad...
- */
-- rxs.mactime = ath5k_extend_tsf(sc->ah, ds->ds_rxstat.rs_tstamp);
-+ rxs.mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp);
- rxs.flag |= RX_FLAG_TSFT;
-
-- rxs.freq = sc->curchan->freq;
-- rxs.channel = sc->curchan->chan;
-- rxs.phymode = sc->curmode;
-+ rxs.freq = sc->curchan->center_freq;
-+ rxs.band = sc->curband->band;
-
- /*
- * signal quality:
-@@ -1803,25 +1905,25 @@
- /* noise floor in dBm, from the last noise calibration */
- rxs.noise = sc->ah->ah_noise_floor;
- /* signal level in dBm */
-- rxs.ssi = rxs.noise + ds->ds_rxstat.rs_rssi;
-+ rxs.ssi = rxs.noise + rs.rs_rssi;
- /*
- * "signal" is actually displayed as Link Quality by iwconfig
- * we provide a percentage based on rssi (assuming max rssi 64)
- */
-- rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64;
-+ rxs.signal = rs.rs_rssi * 100 / 64;
-
-- rxs.antenna = ds->ds_rxstat.rs_antenna;
-- rxs.rate = ds->ds_rxstat.rs_rate;
-- rxs.flag |= ath5k_rx_decrypted(sc, ds, skb);
-+ rxs.antenna = rs.rs_antenna;
-+ rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
-+ rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
-
- ath5k_debug_dump_skb(sc, skb, "RX ", 0);
-
- /* check beacons in IBSS mode */
- if (sc->opmode == IEEE80211_IF_TYPE_IBSS)
-- ath5k_check_ibss_hw_merge(sc, skb);
-+ ath5k_check_ibss_tsf(sc, skb, &rxs);
-
- __ieee80211_rx(sc->hw, skb, &rxs);
-- sc->led_rxrate = ds->ds_rxstat.rs_rate;
-+ sc->led_rxrate = rs.rs_rate;
- ath5k_led_event(sc, ATH_LED_RX);
- next:
- list_move_tail(&bf->list, &sc->rxbuf);
-@@ -1840,6 +1942,7 @@
- ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
- {
- struct ieee80211_tx_status txs = {};
-+ struct ath5k_tx_status ts = {};
- struct ath5k_buf *bf, *bf0;
- struct ath5k_desc *ds;
- struct sk_buff *skb;
-@@ -1852,7 +1955,7 @@
- /* TODO only one segment */
- pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr,
- sc->desc_len, PCI_DMA_FROMDEVICE);
-- ret = sc->ah->ah_proc_tx_desc(sc->ah, ds);
-+ ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
- if (unlikely(ret == -EINPROGRESS))
- break;
- else if (unlikely(ret)) {
-@@ -1867,17 +1970,16 @@
- PCI_DMA_TODEVICE);
-
- txs.control = bf->ctl;
-- txs.retry_count = ds->ds_txstat.ts_shortretry +
-- ds->ds_txstat.ts_longretry / 6;
-- if (unlikely(ds->ds_txstat.ts_status)) {
-+ txs.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
-+ if (unlikely(ts.ts_status)) {
- sc->ll_stats.dot11ACKFailureCount++;
-- if (ds->ds_txstat.ts_status & AR5K_TXERR_XRETRY)
-+ if (ts.ts_status & AR5K_TXERR_XRETRY)
- txs.excessive_retries = 1;
-- else if (ds->ds_txstat.ts_status & AR5K_TXERR_FILT)
-+ else if (ts.ts_status & AR5K_TXERR_FILT)
- txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED;
- } else {
- txs.flags |= IEEE80211_TX_STATUS_ACK;
-- txs.ack_signal = ds->ds_txstat.ts_rssi;
-+ txs.ack_signal = ts.ts_rssi;
- }
-
- ieee80211_tx_status(sc->hw, skb, &txs);
-@@ -1958,8 +2060,9 @@
- ds->ds_data = bf->skbaddr;
- ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
- ieee80211_get_hdrlen_from_skb(skb),
-- AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 1,
-- AR5K_TXKEYIX_INVALID, antenna, flags, 0, 0);
-+ AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
-+ ctl->tx_rate->hw_value, 1, AR5K_TXKEYIX_INVALID,
-+ antenna, flags, 0, 0);
- if (ret)
- goto err_unmap;
-
-@@ -2050,7 +2153,7 @@
- * beacon timer registers.
- *
- * This is called in a variety of situations, e.g. when a beacon is received,
-- * when a HW merge has been detected, but also when an new IBSS is created or
-+ * when a TSF update has been detected, but also when an new IBSS is created or
- * when we otherwise know we have to update the timers, but we keep it in this
- * function to have it all together in one place.
- */
-@@ -2150,7 +2253,7 @@
- * another AP to associate with.
- *
- * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
-- * interrupts to detect HW merges only.
-+ * interrupts to detect TSF updates only.
- *
- * AP mode is missing.
- */
-@@ -2170,7 +2273,7 @@
- * hardware send the beacons automatically. We have to load it
- * only once here.
- * We use the SWBA interrupt only to keep track of the beacon
-- * timers in order to detect HW merges (automatic TSF updates).
-+ * timers in order to detect automatic TSF updates.
- */
- ath5k_beaconq_config(sc);
-
-@@ -2211,7 +2314,8 @@
- * be followed by initialization of the appropriate bits
- * and then setup of the interrupt mask.
- */
-- sc->curchan = sc->hw->conf.chan;
-+ sc->curchan = sc->hw->conf.channel;
-+ sc->curband = &sc->sbands[sc->curchan->band];
- ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false);
- if (ret) {
- ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret);
-@@ -2238,7 +2342,8 @@
- * Enable interrupts.
- */
- sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL |
-- AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL;
-+ AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
-+ AR5K_INT_MIB;
-
- ath5k_hw_set_intr(sc->ah, sc->imask);
- /* Set ack to be sent at low bit-rates */
-@@ -2382,8 +2487,8 @@
- *
- * In IBSS mode we use this interrupt just to
- * keep track of the next TBTT (target beacon
-- * transmission time) in order to detect hardware
-- * merges (TSF updates).
-+ * transmission time) in order to detect wether
-+ * automatic TSF updates happened.
- */
- if (sc->opmode == IEEE80211_IF_TYPE_IBSS) {
- /* XXX: only if VEOL suppported */
-@@ -2418,7 +2523,11 @@
- if (status & AR5K_INT_BMISS) {
- }
- if (status & AR5K_INT_MIB) {
-- /* TODO */
-+ /*
-+ * These stats are also used for ANI i think
-+ * so how about updating them more often ?
-+ */
-+ ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
- }
- }
- } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0);
-@@ -2448,7 +2557,8 @@
- struct ath5k_hw *ah = sc->ah;
-
- ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
-- sc->curchan->chan, sc->curchan->val);
-+ ieee80211_frequency_to_channel(sc->curchan->center_freq),
-+ sc->curchan->hw_value);
-
- if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) {
- /*
-@@ -2460,7 +2570,8 @@
- }
- if (ath5k_hw_phy_calibrate(ah, sc->curchan))
- ATH5K_ERR(sc, "calibration of channel %u failed\n",
-- sc->curchan->chan);
-+ ieee80211_frequency_to_channel(
-+ sc->curchan->center_freq));
-
- mod_timer(&sc->calib_tim, round_jiffies(jiffies +
- msecs_to_jiffies(ath5k_calinterval * 1000)));
-@@ -2558,7 +2669,7 @@
- memmove(skb->data, skb->data+pad, hdrlen);
- }
-
-- sc->led_txrate = ctl->tx_rate;
-+ sc->led_txrate = ctl->tx_rate->hw_value;
-
- spin_lock_irqsave(&sc->txbuflock, flags);
- if (list_empty(&sc->txbuf)) {
-@@ -2597,11 +2708,6 @@
- int ret;
-
- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
-- /*
-- * Convert to a hw channel description with the flags
-- * constrained to reflect the current operating mode.
-- */
-- sc->curchan = hw->conf.chan;
-
- ath5k_hw_set_intr(ah, 0);
- ath5k_txq_cleanup(sc);
-@@ -2692,6 +2798,9 @@
- mutex_unlock(&sc->lock);
- }
-
-+/*
-+ * TODO: Phy disable/diversity etc
-+ */
- static int
- ath5k_config(struct ieee80211_hw *hw,
- struct ieee80211_conf *conf)
-@@ -2699,9 +2808,9 @@
- struct ath5k_softc *sc = hw->priv;
-
- sc->bintval = conf->beacon_int;
-- ath5k_setcurmode(sc, conf->phymode);
-+ sc->power_level = conf->power_level;
-
-- return ath5k_chan_set(sc, conf->chan);
-+ return ath5k_chan_set(sc, conf->channel);
- }
-
- static int
-@@ -2869,7 +2978,9 @@
-
- switch(key->alg) {
- case ALG_WEP:
-- break;
-+ /* XXX: fix hardware encryption, its not working. For now
-+ * allow software encryption */
-+ /* break; */
- case ALG_TKIP:
- case ALG_CCMP:
- return -EOPNOTSUPP;
-@@ -2909,6 +3020,10 @@
- struct ieee80211_low_level_stats *stats)
- {
- struct ath5k_softc *sc = hw->priv;
-+ struct ath5k_hw *ah = sc->ah;
-+
-+ /* Force update */
-+ ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
-
- memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats));
-
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/base.h linux-2.6.25/drivers/net/wireless/ath5k/base.h
---- linux-2.6.25.old/drivers/net/wireless/ath5k/base.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/base.h 2008-04-19 13:54:59.000000000 +0200
-@@ -83,7 +83,7 @@
- #if CHAN_DEBUG
- #define ATH_CHAN_MAX (26+26+26+200+200)
- #else
--#define ATH_CHAN_MAX (14+14+14+252+20) /* XXX what's the max? */
-+#define ATH_CHAN_MAX (14+14+14+252+20)
- #endif
-
- /* Software Carrier, keeps track of the driver state
-@@ -95,15 +95,22 @@
- struct ieee80211_tx_queue_stats tx_stats;
- struct ieee80211_low_level_stats ll_stats;
- struct ieee80211_hw *hw; /* IEEE 802.11 common */
-- struct ieee80211_hw_mode modes[NUM_DRIVER_MODES];
-+ struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
- struct ieee80211_channel channels[ATH_CHAN_MAX];
-- struct ieee80211_rate rates[AR5K_MAX_RATES * NUM_DRIVER_MODES];
-+ struct ieee80211_rate rates[AR5K_MAX_RATES * IEEE80211_NUM_BANDS];
- enum ieee80211_if_types opmode;
- struct ath5k_hw *ah; /* Atheros HW */
-
--#if ATH5K_DEBUG
-+ struct ieee80211_supported_band *curband;
-+
-+ u8 a_rates;
-+ u8 b_rates;
-+ u8 g_rates;
-+ u8 xr_rates;
-+
-+#ifdef CONFIG_ATH5K_DEBUG
- struct ath5k_dbg_info debug; /* debug info */
--#endif
-+#endif /* CONFIG_ATH5K_DEBUG */
-
- struct ath5k_buf *bufptr; /* allocated buffer ptr */
- struct ath5k_desc *desc; /* TX/RX descriptors */
-@@ -169,6 +176,7 @@
- unsigned int nexttbtt; /* next beacon time in TU */
-
- struct timer_list calib_tim; /* calibration timer */
-+ int power_level; /* Requested tx power in dbm */
- };
-
- #define ath5k_hw_hasbssidmask(_ah) \
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/debug.c linux-2.6.25/drivers/net/wireless/ath5k/debug.c
---- linux-2.6.25.old/drivers/net/wireless/ath5k/debug.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/debug.c 2008-04-19 13:54:59.000000000 +0200
-@@ -65,7 +65,7 @@
- module_param_named(debug, ath5k_debug, uint, 0);
-
-
--#if ATH5K_DEBUG
-+#ifdef CONFIG_ATH5K_DEBUG
-
- #include <linux/seq_file.h>
- #include "reg.h"
-@@ -200,7 +200,8 @@
- {
- struct ath5k_softc *sc = file->private_data;
- char buf[100];
-- snprintf(buf, sizeof(buf), "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
-+ snprintf(buf, sizeof(buf), "0x%016llx\n",
-+ (unsigned long long)ath5k_hw_get_tsf64(sc->ah));
- return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
- }
-
-@@ -271,7 +272,8 @@
-
- tsf = ath5k_hw_get_tsf64(sc->ah);
- len += snprintf(buf+len, sizeof(buf)-len,
-- "TSF\t\t0x%016llx\tTU: %08x\n", tsf, TSF_TO_TU(tsf));
-+ "TSF\t\t0x%016llx\tTU: %08x\n",
-+ (unsigned long long)tsf, TSF_TO_TU(tsf));
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
- }
-@@ -340,7 +342,7 @@
- { ATH5K_DEBUG_LED, "led", "LED mamagement" },
- { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
- { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
-- { ATH5K_DEBUG_DUMPMODES, "dumpmodes", "dump modes" },
-+ { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
- { ATH5K_DEBUG_TRACE, "trace", "trace function calls" },
- { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
- };
-@@ -452,43 +454,63 @@
- /* functions used in other places */
-
- void
--ath5k_debug_dump_modes(struct ath5k_softc *sc, struct ieee80211_hw_mode *modes)
-+ath5k_debug_dump_bands(struct ath5k_softc *sc)
- {
-- unsigned int m, i;
-+ unsigned int b, i;
-
-- if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPMODES)))
-+ if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPBANDS)))
- return;
-
-- for (m = 0; m < NUM_DRIVER_MODES; m++) {
-- printk(KERN_DEBUG "Mode %u: channels %d, rates %d\n", m,
-- modes[m].num_channels, modes[m].num_rates);
-+ BUG_ON(!sc->sbands);
-+
-+ for (b = 0; b < IEEE80211_NUM_BANDS; b++) {
-+ struct ieee80211_supported_band *band = &sc->sbands[b];
-+ char bname[5];
-+ switch (band->band) {
-+ case IEEE80211_BAND_2GHZ:
-+ strcpy(bname, "2 GHz");
-+ break;
-+ case IEEE80211_BAND_5GHZ:
-+ strcpy(bname, "5 GHz");
-+ break;
-+ default:
-+ printk(KERN_DEBUG "Band not supported: %d\n",
-+ band->band);
-+ return;
-+ }
-+ printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname,
-+ band->n_channels, band->n_bitrates);
- printk(KERN_DEBUG " channels:\n");
-- for (i = 0; i < modes[m].num_channels; i++)
-+ for (i = 0; i < band->n_channels; i++)
- printk(KERN_DEBUG " %3d %d %.4x %.4x\n",
-- modes[m].channels[i].chan,
-- modes[m].channels[i].freq,
-- modes[m].channels[i].val,
-- modes[m].channels[i].flag);
-+ ieee80211_frequency_to_channel(
-+ band->channels[i].center_freq),
-+ band->channels[i].center_freq,
-+ band->channels[i].hw_value,
-+ band->channels[i].flags);
- printk(KERN_DEBUG " rates:\n");
-- for (i = 0; i < modes[m].num_rates; i++)
-+ for (i = 0; i < band->n_bitrates; i++)
- printk(KERN_DEBUG " %4d %.4x %.4x %.4x\n",
-- modes[m].rates[i].rate,
-- modes[m].rates[i].val,
-- modes[m].rates[i].flags,
-- modes[m].rates[i].val2);
-+ band->bitrates[i].bitrate,
-+ band->bitrates[i].hw_value,
-+ band->bitrates[i].flags,
-+ band->bitrates[i].hw_value_short);
- }
- }
-
- static inline void
--ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done)
-+ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
-+ struct ath5k_rx_status *rs)
- {
- struct ath5k_desc *ds = bf->desc;
-+ struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx;
-
- printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n",
- ds, (unsigned long long)bf->daddr,
-- ds->ds_link, ds->ds_data, ds->ds_ctl0, ds->ds_ctl1,
-- ds->ds_hw[0], ds->ds_hw[1],
-- !done ? ' ' : (ds->ds_rxstat.rs_status == 0) ? '*' : '!');
-+ ds->ds_link, ds->ds_data,
-+ rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1,
-+ rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0,
-+ !done ? ' ' : (rs->rs_status == 0) ? '*' : '!');
- }
-
- void
-@@ -496,6 +518,7 @@
- {
- struct ath5k_desc *ds;
- struct ath5k_buf *bf;
-+ struct ath5k_rx_status rs = {};
- int status;
-
- if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
-@@ -507,9 +530,9 @@
- spin_lock_bh(&sc->rxbuflock);
- list_for_each_entry(bf, &sc->rxbuf, list) {
- ds = bf->desc;
-- status = ah->ah_proc_rx_desc(ah, ds);
-+ status = ah->ah_proc_rx_desc(ah, ds, &rs);
- if (!status)
-- ath5k_debug_printrxbuf(bf, status == 0);
-+ ath5k_debug_printrxbuf(bf, status == 0, &rs);
- }
- spin_unlock_bh(&sc->rxbuflock);
- }
-@@ -533,19 +556,24 @@
- }
-
- void
--ath5k_debug_printtxbuf(struct ath5k_softc *sc,
-- struct ath5k_buf *bf, int done)
-+ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
- {
- struct ath5k_desc *ds = bf->desc;
-+ struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212;
-+ struct ath5k_tx_status ts = {};
-+ int done;
-
- if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
- return;
-
-+ done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
-+
- printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
- "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
-- ds->ds_data, ds->ds_ctl0, ds->ds_ctl1,
-- ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3],
-- !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!');
-+ ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1,
-+ td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3,
-+ td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
-+ done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
- }
-
--#endif /* if ATH5K_DEBUG */
-+#endif /* ifdef CONFIG_ATH5K_DEBUG */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/debug.h linux-2.6.25/drivers/net/wireless/ath5k/debug.h
---- linux-2.6.25.old/drivers/net/wireless/ath5k/debug.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/debug.h 2008-04-19 13:54:59.000000000 +0200
-@@ -61,11 +61,6 @@
- #ifndef _ATH5K_DEBUG_H
- #define _ATH5K_DEBUG_H
-
--/* set this to 1 for debugging output */
--#ifndef ATH5K_DEBUG
--#define ATH5K_DEBUG 0
--#endif
--
- struct ath5k_softc;
- struct ath5k_hw;
- struct ieee80211_hw_mode;
-@@ -96,7 +91,7 @@
- * @ATH5K_DEBUG_LED: led management
- * @ATH5K_DEBUG_DUMP_RX: print received skb content
- * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
-- * @ATH5K_DEBUG_DUMPMODES: dump modes
-+ * @ATH5K_DEBUG_DUMPBANDS: dump bands
- * @ATH5K_DEBUG_TRACE: trace function calls
- * @ATH5K_DEBUG_ANY: show at any debug level
- *
-@@ -118,12 +113,12 @@
- ATH5K_DEBUG_LED = 0x00000080,
- ATH5K_DEBUG_DUMP_RX = 0x00000100,
- ATH5K_DEBUG_DUMP_TX = 0x00000200,
-- ATH5K_DEBUG_DUMPMODES = 0x00000400,
-+ ATH5K_DEBUG_DUMPBANDS = 0x00000400,
- ATH5K_DEBUG_TRACE = 0x00001000,
- ATH5K_DEBUG_ANY = 0xffffffff
- };
-
--#if ATH5K_DEBUG
-+#ifdef CONFIG_ATH5K_DEBUG
-
- #define ATH5K_TRACE(_sc) do { \
- if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \
-@@ -158,20 +153,20 @@
- ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
-
- void
--ath5k_debug_dump_modes(struct ath5k_softc *sc,
-- struct ieee80211_hw_mode *modes);
-+ath5k_debug_dump_bands(struct ath5k_softc *sc);
-
- void
- ath5k_debug_dump_skb(struct ath5k_softc *sc,
- struct sk_buff *skb, const char *prefix, int tx);
-
- void
--ath5k_debug_printtxbuf(struct ath5k_softc *sc,
-- struct ath5k_buf *bf, int done);
-+ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
-
- #else /* no debugging */
-
--#define ATH5K_TRACE(_sc) /* empty */
-+#include <linux/compiler.h>
-+
-+#define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc))
-
- static inline void __attribute__ ((format (printf, 3, 4)))
- ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {}
-@@ -196,17 +191,15 @@
- ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
-
- static inline void
--ath5k_debug_dump_modes(struct ath5k_softc *sc,
-- struct ieee80211_hw_mode *modes) {}
-+ath5k_debug_dump_bands(struct ath5k_softc *sc) {}
-
- static inline void
- ath5k_debug_dump_skb(struct ath5k_softc *sc,
- struct sk_buff *skb, const char *prefix, int tx) {}
-
- static inline void
--ath5k_debug_printtxbuf(struct ath5k_softc *sc,
-- struct ath5k_buf *bf, int done) {}
-+ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {}
-
--#endif /* if ATH5K_DEBUG */
-+#endif /* ifdef CONFIG_ATH5K_DEBUG */
-
- #endif /* ifndef _ATH5K_DEBUG_H */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/hw.c linux-2.6.25/drivers/net/wireless/ath5k/hw.c
---- linux-2.6.25.old/drivers/net/wireless/ath5k/hw.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/hw.c 2008-04-19 13:54:59.000000000 +0200
-@@ -1,4 +1,4 @@
-- /*
-+/*
- * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org>
-@@ -48,14 +48,18 @@
- static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
- unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
- unsigned int);
--static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *);
-+static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *,
-+ struct ath5k_tx_status *);
- static int ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
- unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
- unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
- unsigned int, unsigned int);
--static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *);
--static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *, struct ath5k_desc *);
--static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *, struct ath5k_desc *);
-+static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *,
-+ struct ath5k_tx_status *);
-+static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *, struct ath5k_desc *,
-+ struct ath5k_rx_status *);
-+static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *, struct ath5k_desc *,
-+ struct ath5k_rx_status *);
- static int ath5k_hw_get_capabilities(struct ath5k_hw *);
-
- static int ath5k_eeprom_init(struct ath5k_hw *);
-@@ -81,12 +85,12 @@
-
- static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
- {
-- return turbo == true ? (usec * 80) : (usec * 40);
-+ return turbo ? (usec * 80) : (usec * 40);
- }
-
- static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
- {
-- return turbo == true ? (clock / 80) : (clock / 40);
-+ return turbo ? (clock / 80) : (clock / 40);
- }
-
- /*
-@@ -100,7 +104,7 @@
-
- for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
- data = ath5k_hw_reg_read(ah, reg);
-- if ((is_set == true) && (data & flag))
-+ if (is_set && (data & flag))
- break;
- else if ((data & flag) == val)
- break;
-@@ -116,11 +120,69 @@
- \***************************************/
-
- /*
-+ * Power On Self Test helper function
-+ */
-+static int ath5k_hw_post(struct ath5k_hw *ah)
-+{
-+
-+ int i, c;
-+ u16 cur_reg;
-+ u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
-+ u32 var_pattern;
-+ u32 static_pattern[4] = {
-+ 0x55555555, 0xaaaaaaaa,
-+ 0x66666666, 0x99999999
-+ };
-+ u32 init_val;
-+ u32 cur_val;
-+
-+ for (c = 0; c < 2; c++) {
-+
-+ cur_reg = regs[c];
-+ init_val = ath5k_hw_reg_read(ah, cur_reg);
-+
-+ for (i = 0; i < 256; i++) {
-+ var_pattern = i << 16 | i;
-+ ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-+ cur_val = ath5k_hw_reg_read(ah, cur_reg);
-+
-+ if (cur_val != var_pattern) {
-+ ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
-+ return -EAGAIN;
-+ }
-+
-+ /* Found on ndiswrapper dumps */
-+ var_pattern = 0x0039080f;
-+ ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-+ }
-+
-+ for (i = 0; i < 4; i++) {
-+ var_pattern = static_pattern[i];
-+ ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-+ cur_val = ath5k_hw_reg_read(ah, cur_reg);
-+
-+ if (cur_val != var_pattern) {
-+ ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
-+ return -EAGAIN;
-+ }
-+
-+ /* Found on ndiswrapper dumps */
-+ var_pattern = 0x003b080f;
-+ ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-+ }
-+ }
-+
-+ return 0;
-+
-+}
-+
-+/*
- * Check if the device is supported and initialize the needed structs
- */
- struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
- {
- struct ath5k_hw *ah;
-+ struct pci_dev *pdev = sc->pdev;
- u8 mac[ETH_ALEN];
- int ret;
- u32 srev;
-@@ -140,9 +202,6 @@
- * HW information
- */
-
-- /* Get reg domain from eeprom */
-- ath5k_get_regdomain(ah);
--
- ah->ah_op_mode = IEEE80211_IF_TYPE_STA;
- ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
- ah->ah_turbo = false;
-@@ -177,9 +236,9 @@
- }
-
- if (ah->ah_version == AR5K_AR5212)
-- ah->ah_proc_rx_desc = ath5k_hw_proc_new_rx_status;
-+ ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
- else if (ah->ah_version <= AR5K_AR5211)
-- ah->ah_proc_rx_desc = ath5k_hw_proc_old_rx_status;
-+ ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
-
- /* Bring device out of sleep and reset it's units */
- ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true);
-@@ -203,15 +262,19 @@
- CHANNEL_2GHZ);
-
- /* Return on unsuported chips (unsupported eeprom etc) */
-- if(srev >= AR5K_SREV_VER_AR5416){
-+ if ((srev >= AR5K_SREV_VER_AR5416) &&
-+ (srev < AR5K_SREV_VER_AR2425)) {
- ATH5K_ERR(sc, "Device not yet supported.\n");
- ret = -ENODEV;
- goto err_free;
-+ } else if (srev == AR5K_SREV_VER_AR2425) {
-+ ATH5K_WARN(sc, "Support for RF2425 is under development.\n");
- }
-
- /* Identify single chip solutions */
-- if((srev <= AR5K_SREV_VER_AR5414) &&
-- (srev >= AR5K_SREV_VER_AR2424)) {
-+ if (((srev <= AR5K_SREV_VER_AR5414) &&
-+ (srev >= AR5K_SREV_VER_AR2413)) ||
-+ (srev == AR5K_SREV_VER_AR2425)) {
- ah->ah_single_chip = true;
- } else {
- ah->ah_single_chip = false;
-@@ -226,15 +289,81 @@
- ah->ah_radio = AR5K_RF5110;
- } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
- ah->ah_radio = AR5K_RF5111;
-- } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
-+ ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
-+ } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
-+
- ah->ah_radio = AR5K_RF5112;
-+
-+ if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
-+ ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
- } else {
-+ ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
-+ }
-+
-+ } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
-+ ah->ah_radio = AR5K_RF2413;
-+ ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
-+ } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
-+
- ah->ah_radio = AR5K_RF5413;
-+
-+ if (ah->ah_mac_srev <= AR5K_SREV_VER_AR5424 &&
-+ ah->ah_mac_srev >= AR5K_SREV_VER_AR2424)
-+ ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424;
-+ else
-+ ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
-+ /*
-+ * Register returns 0x4 for radio revision
-+ * so ath5k_hw_radio_revision doesn't parse the value
-+ * correctly. For now we are based on mac's srev to
-+ * identify RF2425 radio.
-+ */
-+ } else if (srev == AR5K_SREV_VER_AR2425) {
-+ ah->ah_radio = AR5K_RF2425;
-+ ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
- }
-
- ah->ah_phy = AR5K_PHY(0);
-
- /*
-+ * Identify AR5212-based PCI-E cards
-+ * And write some initial settings.
-+ *
-+ * (doing a "strings" on ndis driver
-+ * -ar5211.sys- reveals the following
-+ * pci-e related functions:
-+ *
-+ * pcieClockReq
-+ * pcieRxErrNotify
-+ * pcieL1SKPEnable
-+ * pcieAspm
-+ * pcieDisableAspmOnRfWake
-+ * pciePowerSaveEnable
-+ *
-+ * I guess these point to ClockReq but
-+ * i'm not sure.)
-+ */
-+ if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
-+ ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
-+ ath5k_hw_reg_write(ah, 0x24924924, 0x4080);
-+ ath5k_hw_reg_write(ah, 0x28000039, 0x4080);
-+ ath5k_hw_reg_write(ah, 0x53160824, 0x4080);
-+ ath5k_hw_reg_write(ah, 0xe5980579, 0x4080);
-+ ath5k_hw_reg_write(ah, 0x001defff, 0x4080);
-+ ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080);
-+ ath5k_hw_reg_write(ah, 0xbe105554, 0x4080);
-+ ath5k_hw_reg_write(ah, 0x000e3007, 0x4080);
-+ ath5k_hw_reg_write(ah, 0x00000000, 0x4084);
-+ }
-+
-+ /*
-+ * POST
-+ */
-+ ret = ath5k_hw_post(ah);
-+ if (ret)
-+ goto err_free;
-+
-+ /*
- * Get card capabilities, values, ...
- */
-
-@@ -280,7 +409,8 @@
- */
- static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
- {
-- u32 turbo, mode, clock;
-+ struct pci_dev *pdev = ah->ah_sc->pdev;
-+ u32 turbo, mode, clock, bus_flags;
- int ret;
-
- turbo = 0;
-@@ -357,10 +487,16 @@
- AR5K_PHY_TURBO);
- }
-
-- /* ...reset chipset and PCI device */
-- if (ah->ah_single_chip == false && ath5k_hw_nic_reset(ah,
-- AR5K_RESET_CTL_CHIP | AR5K_RESET_CTL_PCI)) {
-- ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip + PCI\n");
-+ /* reseting PCI on PCI-E cards results card to hang
-+ * and always return 0xffff... so we ingore that flag
-+ * for PCI-E cards */
-+ bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
-+
-+ /* Reset chipset */
-+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
-+ AR5K_RESET_CTL_BASEBAND | bus_flags);
-+ if (ret) {
-+ ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
- return -EIO;
- }
-
-@@ -405,15 +541,15 @@
-
- /* Get rate tables */
- switch (mode) {
-- case MODE_IEEE80211A:
-+ case AR5K_MODE_11A:
- return &ath5k_rt_11a;
-- case MODE_ATHEROS_TURBO:
-+ case AR5K_MODE_11A_TURBO:
- return &ath5k_rt_turbo;
-- case MODE_IEEE80211B:
-+ case AR5K_MODE_11B:
- return &ath5k_rt_11b;
-- case MODE_IEEE80211G:
-+ case AR5K_MODE_11G:
- return &ath5k_rt_11g;
-- case MODE_ATHEROS_TURBOG:
-+ case AR5K_MODE_11G_TURBO:
- return &ath5k_rt_xr;
- }
-
-@@ -459,15 +595,15 @@
- ds_coef_exp, ds_coef_man, clock;
-
- if (!(ah->ah_version == AR5K_AR5212) ||
-- !(channel->val & CHANNEL_OFDM))
-+ !(channel->hw_value & CHANNEL_OFDM))
- BUG();
-
- /* Seems there are two PLLs, one for baseband sampling and one
- * for tuning. Tuning basebands are 40 MHz or 80MHz when in
- * turbo. */
-- clock = channel->val & CHANNEL_TURBO ? 80 : 40;
-+ clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
- coef_scaled = ((5 * (clock << 24)) / 2) /
-- channel->freq;
-+ channel->center_freq;
-
- for (coef_exp = 31; coef_exp > 0; coef_exp--)
- if ((coef_scaled >> coef_exp) & 0x1)
-@@ -494,8 +630,7 @@
- * ath5k_hw_write_rate_duration - set rate duration during hw resets
- *
- * @ah: the &struct ath5k_hw
-- * @driver_mode: one of enum ieee80211_phymode or our one of our own
-- * vendor modes
-+ * @mode: one of enum ath5k_driver_mode
- *
- * Write the rate duration table for the current mode upon hw reset. This
- * is a helper for ath5k_hw_reset(). It seems all this is doing is setting
-@@ -506,19 +641,20 @@
- *
- */
- static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
-- unsigned int driver_mode)
-+ unsigned int mode)
- {
- struct ath5k_softc *sc = ah->ah_sc;
- const struct ath5k_rate_table *rt;
-+ struct ieee80211_rate srate = {};
- unsigned int i;
-
- /* Get rate table for the current operating mode */
-- rt = ath5k_hw_get_rate_table(ah,
-- driver_mode);
-+ rt = ath5k_hw_get_rate_table(ah, mode);
-
- /* Write rate duration table */
- for (i = 0; i < rt->rate_count; i++) {
- const struct ath5k_rate *rate, *control_rate;
-+
- u32 reg;
- u16 tx_time;
-
-@@ -528,14 +664,16 @@
- /* Set ACK timeout */
- reg = AR5K_RATE_DUR(rate->rate_code);
-
-+ srate.bitrate = control_rate->rate_kbps/100;
-+
- /* An ACK frame consists of 10 bytes. If you add the FCS,
- * which ieee80211_generic_frame_duration() adds,
- * its 14 bytes. Note we use the control rate and not the
- * actual rate for this rate. See mac80211 tx.c
- * ieee80211_duration() for a brief description of
- * what rate we should choose to TX ACKs. */
-- tx_time = ieee80211_generic_frame_duration(sc->hw,
-- sc->vif, 10, control_rate->rate_kbps/100);
-+ tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
-+ sc->vif, 10, &srate));
-
- ath5k_hw_reg_write(ah, tx_time, reg);
-
-@@ -568,8 +706,9 @@
- struct ieee80211_channel *channel, bool change_channel)
- {
- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-- u32 data, s_seq, s_ant, s_led[3];
-- unsigned int i, mode, freq, ee_mode, ant[2], driver_mode = -1;
-+ struct pci_dev *pdev = ah->ah_sc->pdev;
-+ u32 data, s_seq, s_ant, s_led[3], dma_size;
-+ unsigned int i, mode, freq, ee_mode, ant[2];
- int ret;
-
- ATH5K_TRACE(ah->ah_sc);
-@@ -585,7 +724,7 @@
- */
- /*DCU/Antenna selection not available on 5210*/
- if (ah->ah_version != AR5K_AR5210) {
-- if (change_channel == true) {
-+ if (change_channel) {
- /* Seq number for queue 0 -do this for all queues ? */
- s_seq = ath5k_hw_reg_read(ah,
- AR5K_QUEUE_DFS_SEQNUM(0));
-@@ -599,12 +738,12 @@
- s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
- s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
-
-- if (change_channel == true && ah->ah_rf_banks != NULL)
-+ if (change_channel && ah->ah_rf_banks != NULL)
- ath5k_hw_get_rf_gain(ah);
-
-
- /*Wakeup the device*/
-- ret = ath5k_hw_nic_wakeup(ah, channel->val, false);
-+ ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
- if (ret)
- return ret;
-
-@@ -620,43 +759,40 @@
- if (ah->ah_version != AR5K_AR5210) {
- if (ah->ah_radio != AR5K_RF5111 &&
- ah->ah_radio != AR5K_RF5112 &&
-- ah->ah_radio != AR5K_RF5413) {
-+ ah->ah_radio != AR5K_RF5413 &&
-+ ah->ah_radio != AR5K_RF2413 &&
-+ ah->ah_radio != AR5K_RF2425) {
- ATH5K_ERR(ah->ah_sc,
- "invalid phy radio: %u\n", ah->ah_radio);
- return -EINVAL;
- }
-
-- switch (channel->val & CHANNEL_MODES) {
-+ switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
-- mode = AR5K_INI_VAL_11A;
-+ mode = AR5K_MODE_11A;
- freq = AR5K_INI_RFGAIN_5GHZ;
- ee_mode = AR5K_EEPROM_MODE_11A;
-- driver_mode = MODE_IEEE80211A;
- break;
- case CHANNEL_G:
-- mode = AR5K_INI_VAL_11G;
-+ mode = AR5K_MODE_11G;
- freq = AR5K_INI_RFGAIN_2GHZ;
- ee_mode = AR5K_EEPROM_MODE_11G;
-- driver_mode = MODE_IEEE80211G;
- break;
- case CHANNEL_B:
-- mode = AR5K_INI_VAL_11B;
-+ mode = AR5K_MODE_11B;
- freq = AR5K_INI_RFGAIN_2GHZ;
- ee_mode = AR5K_EEPROM_MODE_11B;
-- driver_mode = MODE_IEEE80211B;
- break;
- case CHANNEL_T:
-- mode = AR5K_INI_VAL_11A_TURBO;
-+ mode = AR5K_MODE_11A_TURBO;
- freq = AR5K_INI_RFGAIN_5GHZ;
- ee_mode = AR5K_EEPROM_MODE_11A;
-- driver_mode = MODE_ATHEROS_TURBO;
- break;
- /*Is this ok on 5211 too ?*/
- case CHANNEL_TG:
-- mode = AR5K_INI_VAL_11G_TURBO;
-+ mode = AR5K_MODE_11G_TURBO;
- freq = AR5K_INI_RFGAIN_2GHZ;
- ee_mode = AR5K_EEPROM_MODE_11G;
-- driver_mode = MODE_ATHEROS_TURBOG;
- break;
- case CHANNEL_XR:
- if (ah->ah_version == AR5K_AR5211) {
-@@ -664,14 +800,13 @@
- "XR mode not available on 5211");
- return -EINVAL;
- }
-- mode = AR5K_INI_VAL_XR;
-+ mode = AR5K_MODE_XR;
- freq = AR5K_INI_RFGAIN_5GHZ;
- ee_mode = AR5K_EEPROM_MODE_11A;
-- driver_mode = MODE_IEEE80211A;
- break;
- default:
- ATH5K_ERR(ah->ah_sc,
-- "invalid channel: %d\n", channel->freq);
-+ "invalid channel: %d\n", channel->center_freq);
- return -EINVAL;
- }
-
-@@ -701,15 +836,26 @@
- /*
- * Write some more initial register settings
- */
-- if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */
-+ if (ah->ah_version == AR5K_AR5212) {
- ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11));
-
-- if (channel->val == CHANNEL_G)
-- ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */
-+ if (channel->hw_value == CHANNEL_G)
-+ if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
-+ ath5k_hw_reg_write(ah, 0x00f80d80,
-+ AR5K_PHY(83));
-+ else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
-+ ath5k_hw_reg_write(ah, 0x00380140,
-+ AR5K_PHY(83));
-+ else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
-+ ath5k_hw_reg_write(ah, 0x00fc0ec0,
-+ AR5K_PHY(83));
-+ else /* 2425 */
-+ ath5k_hw_reg_write(ah, 0x00fc0fc0,
-+ AR5K_PHY(83));
- else
-- ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83));
-+ ath5k_hw_reg_write(ah, 0x00000000,
-+ AR5K_PHY(83));
-
-- ath5k_hw_reg_write(ah, 0x000001b5, 0xa228); /* 0x000009b5 */
- ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
- ath5k_hw_reg_write(ah, 0x0000000f, 0x8060);
- ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
-@@ -722,7 +868,7 @@
- AR5K_SREV_RAD_5112A) {
- ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
- AR5K_PHY_CCKTXCTL);
-- if (channel->val & CHANNEL_5GHZ)
-+ if (channel->hw_value & CHANNEL_5GHZ)
- data = 0xffb81020;
- else
- data = 0xffb80d20;
-@@ -742,7 +888,7 @@
- * mac80211 are integrated */
- if (ah->ah_version == AR5K_AR5212 &&
- ah->ah_sc->vif != NULL)
-- ath5k_hw_write_rate_duration(ah, driver_mode);
-+ ath5k_hw_write_rate_duration(ah, mode);
-
- /*
- * Write RF registers
-@@ -758,7 +904,7 @@
-
- /* Write OFDM timings on 5212*/
- if (ah->ah_version == AR5K_AR5212 &&
-- channel->val & CHANNEL_OFDM) {
-+ channel->hw_value & CHANNEL_OFDM) {
- ret = ath5k_hw_write_ofdm_timings(ah, channel);
- if (ret)
- return ret;
-@@ -767,7 +913,7 @@
- /*Enable/disable 802.11b mode on 5111
- (enable 2111 frequency converter + CCK)*/
- if (ah->ah_radio == AR5K_RF5111) {
-- if (driver_mode == MODE_IEEE80211B)
-+ if (mode == AR5K_MODE_11B)
- AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
- AR5K_TXCFG_B_MODE);
- else
-@@ -885,13 +1031,24 @@
-
- /*
- * Set Rx/Tx DMA Configuration
-- *(passing dma size not available on 5210)
-+ *
-+ * Set maximum DMA size (512) except for PCI-E cards since
-+ * it causes rx overruns and tx errors (tested on 5424 but since
-+ * rx overruns also occur on 5416/5418 with madwifi we set 128
-+ * for all PCI-E cards to be safe).
-+ *
-+ * In dumps this is 128 for allchips.
-+ *
-+ * XXX: need to check 5210 for this
-+ * TODO: Check out tx triger level, it's always 64 on dumps but I
-+ * guess we can tweak it and see how it goes ;-)
- */
-+ dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
- if (ah->ah_version != AR5K_AR5210) {
-- AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_SDMAMR,
-- AR5K_DMASIZE_512B | AR5K_TXCFG_DMASIZE);
-- AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_SDMAMW,
-- AR5K_DMASIZE_512B);
-+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
-+ AR5K_TXCFG_SDMAMR, dma_size);
-+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
-+ AR5K_RXCFG_SDMAMW, dma_size);
- }
-
- /*
-@@ -905,7 +1062,7 @@
- if (ah->ah_version != AR5K_AR5210) {
- data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
- AR5K_PHY_RX_DELAY_M;
-- data = (channel->val & CHANNEL_CCK) ?
-+ data = (channel->hw_value & CHANNEL_CCK) ?
- ((data << 2) / 22) : (data / 10);
-
- udelay(100 + data);
-@@ -922,11 +1079,11 @@
- if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
- AR5K_PHY_AGCCTL_CAL, 0, false)) {
- ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
-- channel->freq);
-+ channel->center_freq);
- return -EAGAIN;
- }
-
-- ret = ath5k_hw_noise_floor_calibration(ah, channel->freq);
-+ ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
- if (ret)
- return ret;
-
-@@ -934,7 +1091,7 @@
-
- /* A and G modes can use QAM modulation which requires enabling
- * I and Q calibration. Don't bother in B mode. */
-- if (!(driver_mode == MODE_IEEE80211B)) {
-+ if (!(mode == AR5K_MODE_11B)) {
- ah->ah_calibration = true;
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
- AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
-@@ -981,6 +1138,8 @@
-
- /*
- * Set the 32MHz reference clock on 5212 phy clock sleep register
-+ *
-+ * TODO: Find out how to switch to external 32Khz clock to save power
- */
- if (ah->ah_version == AR5K_AR5212) {
- ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
-@@ -988,9 +1147,15 @@
- ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
- ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
- ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
-- ath5k_hw_reg_write(ah, ah->ah_radio == AR5K_RF5111 ?
-- AR5K_PHY_SPENDING_RF5111 : AR5K_PHY_SPENDING_RF5112,
-- AR5K_PHY_SPENDING);
-+ ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
-+ }
-+
-+ if (ah->ah_version == AR5K_AR5212) {
-+ ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
-+ ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
-+ ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
-+ if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
-+ ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
- }
-
- /*
-@@ -1065,7 +1230,7 @@
- staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
- /* fallthrough */
- case AR5K_PM_NETWORK_SLEEP:
-- if (set_chip == true)
-+ if (set_chip)
- ath5k_hw_reg_write(ah,
- AR5K_SLEEP_CTL_SLE | sleep_duration,
- AR5K_SLEEP_CTL);
-@@ -1074,7 +1239,7 @@
- break;
-
- case AR5K_PM_FULL_SLEEP:
-- if (set_chip == true)
-+ if (set_chip)
- ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
- AR5K_SLEEP_CTL);
-
-@@ -1082,7 +1247,7 @@
- break;
-
- case AR5K_PM_AWAKE:
-- if (set_chip == false)
-+ if (!set_chip)
- goto commit;
-
- ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
-@@ -1389,7 +1554,7 @@
- trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
- AR5K_TXCFG_TXFULL);
-
-- if (increase == false) {
-+ if (!increase) {
- if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
- goto done;
- } else
-@@ -1592,9 +1757,10 @@
- /*
- * Write to eeprom - currently disabled, use at your own risk
- */
-+#if 0
- static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data)
- {
--#if 0
-+
- u32 status, timeout;
-
- ATH5K_TRACE(ah->ah_sc);
-@@ -1636,10 +1802,11 @@
- }
- udelay(15);
- }
--#endif
-+
- ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!");
- return -EIO;
- }
-+#endif
-
- /*
- * Translate binary channel representation in EEPROM to frequency
-@@ -2045,50 +2212,6 @@
- }
-
- /*
-- * Read/Write regulatory domain
-- */
--static bool ath5k_eeprom_regulation_domain(struct ath5k_hw *ah, bool write,
-- enum ath5k_regdom *regdomain)
--{
-- u16 ee_regdomain;
--
-- /* Read current value */
-- if (write != true) {
-- ee_regdomain = ah->ah_capabilities.cap_eeprom.ee_regdomain;
-- *regdomain = ath5k_regdom_to_ieee(ee_regdomain);
-- return true;
-- }
--
-- ee_regdomain = ath5k_regdom_from_ieee(*regdomain);
--
-- /* Try to write a new value */
-- if (ah->ah_capabilities.cap_eeprom.ee_protect &
-- AR5K_EEPROM_PROTECT_WR_128_191)
-- return false;
-- if (ath5k_hw_eeprom_write(ah, AR5K_EEPROM_REG_DOMAIN, ee_regdomain)!=0)
-- return false;
--
-- ah->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain;
--
-- return true;
--}
--
--/*
-- * Use the above to write a new regulatory domain
-- */
--int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain)
--{
-- enum ath5k_regdom ieee_regdomain;
--
-- ieee_regdomain = ath5k_regdom_to_ieee(regdomain);
--
-- if (ath5k_eeprom_regulation_domain(ah, true, &ieee_regdomain) == true)
-- return 0;
--
-- return -EIO;
--}
--
--/*
- * Fill the capabilities struct
- */
- static int ath5k_hw_get_capabilities(struct ath5k_hw *ah)
-@@ -2110,8 +2233,8 @@
- ah->ah_capabilities.cap_range.range_2ghz_max = 0;
-
- /* Set supported modes */
-- __set_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode);
-- __set_bit(MODE_ATHEROS_TURBO, ah->ah_capabilities.cap_mode);
-+ __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
-+ __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
- } else {
- /*
- * XXX The tranceiver supports frequencies from 4920 to 6100GHz
-@@ -2133,12 +2256,12 @@
- ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
-
- /* Set supported modes */
-- __set_bit(MODE_IEEE80211A,
-+ __set_bit(AR5K_MODE_11A,
- ah->ah_capabilities.cap_mode);
-- __set_bit(MODE_ATHEROS_TURBO,
-+ __set_bit(AR5K_MODE_11A_TURBO,
- ah->ah_capabilities.cap_mode);
- if (ah->ah_version == AR5K_AR5212)
-- __set_bit(MODE_ATHEROS_TURBOG,
-+ __set_bit(AR5K_MODE_11G_TURBO,
- ah->ah_capabilities.cap_mode);
- }
-
-@@ -2150,11 +2273,11 @@
- ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
-
- if (AR5K_EEPROM_HDR_11B(ee_header))
-- __set_bit(MODE_IEEE80211B,
-+ __set_bit(AR5K_MODE_11B,
- ah->ah_capabilities.cap_mode);
-
- if (AR5K_EEPROM_HDR_11G(ee_header))
-- __set_bit(MODE_IEEE80211G,
-+ __set_bit(AR5K_MODE_11G,
- ah->ah_capabilities.cap_mode);
- }
- }
-@@ -2279,8 +2402,8 @@
- * Set simple BSSID mask on 5212
- */
- if (ah->ah_version == AR5K_AR5212) {
-- ath5k_hw_reg_write(ah, 0xfffffff, AR5K_BSS_IDM0);
-- ath5k_hw_reg_write(ah, 0xfffffff, AR5K_BSS_IDM1);
-+ ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0);
-+ ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1);
- }
-
- /*
-@@ -2425,6 +2548,8 @@
- {
- ATH5K_TRACE(ah->ah_sc);
- AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-+
-+ /* TODO: ANI Support */
- }
-
- /*
-@@ -2434,6 +2559,8 @@
- {
- ATH5K_TRACE(ah->ah_sc);
- AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-+
-+ /* TODO: ANI Support */
- }
-
- /*
-@@ -2828,15 +2955,19 @@
- * Update mib counters (statistics)
- */
- void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
-- struct ath5k_mib_stats *statistics)
-+ struct ieee80211_low_level_stats *stats)
- {
- ATH5K_TRACE(ah->ah_sc);
-+
- /* Read-And-Clear */
-- statistics->ackrcv_bad += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
-- statistics->rts_bad += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
-- statistics->rts_good += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
-- statistics->fcs_bad += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
-- statistics->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
-+ stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
-+ stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
-+ stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
-+ stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
-+
-+ /* XXX: Should we use this to track beacon count ?
-+ * -we read it anyway to clear the register */
-+ ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
-
- /* Reset profile count registers on 5212*/
- if (ah->ah_version == AR5K_AR5212) {
-@@ -2937,8 +3068,16 @@
- for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
- ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
-
-- /* Set NULL encryption on non-5210*/
-- if (ah->ah_version != AR5K_AR5210)
-+ /*
-+ * Set NULL encryption on AR5212+
-+ *
-+ * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
-+ * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
-+ *
-+ * Note2: Windows driver (ndiswrapper) sets this to
-+ * 0x00000714 instead of 0x00000007
-+ */
-+ if (ah->ah_version > AR5K_AR5211)
- ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
- AR5K_KEYTABLE_TYPE(entry));
-
-@@ -3186,19 +3325,19 @@
- return 0;
-
- /* Set Slot time */
-- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
-+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
- AR5K_SLOT_TIME);
- /* Set ACK_CTS timeout */
-- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
-+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
- AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
- /* Set Transmit Latency */
-- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
-+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_TRANSMIT_LATENCY_TURBO :
- AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
- /* Set IFS0 */
-- if (ah->ah_turbo == true)
-+ if (ah->ah_turbo)
- ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
- (ah->ah_aifs + tq->tqi_aifs) *
- AR5K_INIT_SLOT_TIME_TURBO) <<
-@@ -3211,16 +3350,16 @@
- AR5K_INIT_SIFS, AR5K_IFS0);
-
- /* Set IFS1 */
-- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
-+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
- AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
- AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
- /* Set PHY register 0x9844 (??) */
-- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
-+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
- (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 :
- (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C,
- AR5K_PHY(17));
- /* Set Frame Control Register */
-- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
-+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
- (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
- AR5K_PHY_TURBO_SHORT | 0x2020) :
- (AR5K_PHY_FRAME_CTL_INI | 0x1020),
-@@ -3259,7 +3398,7 @@
- /*
- * Calculate and set retry limits
- */
-- if (ah->ah_software_retry == true) {
-+ if (ah->ah_software_retry) {
- /* XXX Need to test this */
- retry_lg = ah->ah_limit_tx_retries;
- retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
-@@ -3507,10 +3646,10 @@
- unsigned int rtscts_rate, unsigned int rtscts_duration)
- {
- u32 frame_type;
-- struct ath5k_hw_2w_tx_desc *tx_desc;
-+ struct ath5k_hw_2w_tx_ctl *tx_ctl;
- unsigned int frame_len;
-
-- tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0;
-+ tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
-
- /*
- * Validate input
-@@ -3529,12 +3668,8 @@
- return -EINVAL;
- }
-
-- /* Clear status descriptor */
-- memset(desc->ds_hw, 0, sizeof(struct ath5k_hw_tx_status));
--
-- /* Initialize control descriptor */
-- tx_desc->tx_control_0 = 0;
-- tx_desc->tx_control_1 = 0;
-+ /* Clear descriptor */
-+ memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
-
- /* Setup control descriptor */
-
-@@ -3546,7 +3681,7 @@
- if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
- return -EINVAL;
-
-- tx_desc->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
-+ tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
-
- /* Verify and set buffer length */
-
-@@ -3557,7 +3692,7 @@
- if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
- return -EINVAL;
-
-- tx_desc->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
-+ tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
-
- /*
- * Verify and set header length
-@@ -3566,7 +3701,7 @@
- if (ah->ah_version == AR5K_AR5210) {
- if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
- return -EINVAL;
-- tx_desc->tx_control_0 |=
-+ tx_ctl->tx_control_0 |=
- AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
- }
-
-@@ -3582,19 +3717,19 @@
- frame_type = type /*<< 2 ?*/;
- }
-
-- tx_desc->tx_control_0 |=
-+ tx_ctl->tx_control_0 |=
- AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
- AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
- } else {
-- tx_desc->tx_control_0 |=
-+ tx_ctl->tx_control_0 |=
- AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
- AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
-- tx_desc->tx_control_1 |=
-+ tx_ctl->tx_control_1 |=
- AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
- }
- #define _TX_FLAGS(_c, _flag) \
- if (flags & AR5K_TXDESC_##_flag) \
-- tx_desc->tx_control_##_c |= \
-+ tx_ctl->tx_control_##_c |= \
- AR5K_2W_TX_DESC_CTL##_c##_##_flag
-
- _TX_FLAGS(0, CLRDMASK);
-@@ -3609,9 +3744,9 @@
- * WEP crap
- */
- if (key_index != AR5K_TXKEYIX_INVALID) {
-- tx_desc->tx_control_0 |=
-+ tx_ctl->tx_control_0 |=
- AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
-- tx_desc->tx_control_1 |=
-+ tx_ctl->tx_control_1 |=
- AR5K_REG_SM(key_index,
- AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
- }
-@@ -3621,7 +3756,7 @@
- */
- if ((ah->ah_version == AR5K_AR5210) &&
- (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
-- tx_desc->tx_control_1 |= rtscts_duration &
-+ tx_ctl->tx_control_1 |= rtscts_duration &
- AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
-
- return 0;
-@@ -3637,13 +3772,11 @@
- unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate,
- unsigned int rtscts_duration)
- {
-- struct ath5k_hw_4w_tx_desc *tx_desc;
-- struct ath5k_hw_tx_status *tx_status;
-+ struct ath5k_hw_4w_tx_ctl *tx_ctl;
- unsigned int frame_len;
-
- ATH5K_TRACE(ah->ah_sc);
-- tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
-- tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2];
-+ tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
-
- /*
- * Validate input
-@@ -3662,14 +3795,8 @@
- return -EINVAL;
- }
-
-- /* Clear status descriptor */
-- memset(tx_status, 0, sizeof(struct ath5k_hw_tx_status));
--
-- /* Initialize control descriptor */
-- tx_desc->tx_control_0 = 0;
-- tx_desc->tx_control_1 = 0;
-- tx_desc->tx_control_2 = 0;
-- tx_desc->tx_control_3 = 0;
-+ /* Clear descriptor */
-+ memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
-
- /* Setup control descriptor */
-
-@@ -3681,7 +3808,7 @@
- if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
- return -EINVAL;
-
-- tx_desc->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
-+ tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
-
- /* Verify and set buffer length */
-
-@@ -3692,20 +3819,20 @@
- if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
- return -EINVAL;
-
-- tx_desc->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
-+ tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
-
-- tx_desc->tx_control_0 |=
-+ tx_ctl->tx_control_0 |=
- AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
- AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
-- tx_desc->tx_control_1 |= AR5K_REG_SM(type,
-+ tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
- AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
-- tx_desc->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
-+ tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
-- tx_desc->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
-+ tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
-
- #define _TX_FLAGS(_c, _flag) \
- if (flags & AR5K_TXDESC_##_flag) \
-- tx_desc->tx_control_##_c |= \
-+ tx_ctl->tx_control_##_c |= \
- AR5K_4W_TX_DESC_CTL##_c##_##_flag
-
- _TX_FLAGS(0, CLRDMASK);
-@@ -3721,8 +3848,8 @@
- * WEP crap
- */
- if (key_index != AR5K_TXKEYIX_INVALID) {
-- tx_desc->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
-- tx_desc->tx_control_1 |= AR5K_REG_SM(key_index,
-+ tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
-+ tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
- AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
- }
-
-@@ -3733,9 +3860,9 @@
- if ((flags & AR5K_TXDESC_RTSENA) &&
- (flags & AR5K_TXDESC_CTSENA))
- return -EINVAL;
-- tx_desc->tx_control_2 |= rtscts_duration &
-+ tx_ctl->tx_control_2 |= rtscts_duration &
- AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
-- tx_desc->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
-+ tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
- AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
- }
-
-@@ -3750,7 +3877,7 @@
- unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
- unsigned int tx_rate3, u_int tx_tries3)
- {
-- struct ath5k_hw_4w_tx_desc *tx_desc;
-+ struct ath5k_hw_4w_tx_ctl *tx_ctl;
-
- /*
- * Rates can be 0 as long as the retry count is 0 too.
-@@ -3767,14 +3894,14 @@
- }
-
- if (ah->ah_version == AR5K_AR5212) {
-- tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
-+ tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
-
- #define _XTX_TRIES(_n) \
- if (tx_tries##_n) { \
-- tx_desc->tx_control_2 |= \
-+ tx_ctl->tx_control_2 |= \
- AR5K_REG_SM(tx_tries##_n, \
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
-- tx_desc->tx_control_3 |= \
-+ tx_ctl->tx_control_3 |= \
- AR5K_REG_SM(tx_rate##_n, \
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
- }
-@@ -3795,13 +3922,15 @@
- * Proccess the tx status descriptor on 5210/5211
- */
- static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
-- struct ath5k_desc *desc)
-+ struct ath5k_desc *desc, struct ath5k_tx_status *ts)
- {
-+ struct ath5k_hw_2w_tx_ctl *tx_ctl;
- struct ath5k_hw_tx_status *tx_status;
-- struct ath5k_hw_2w_tx_desc *tx_desc;
-
-- tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0;
-- tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[0];
-+ ATH5K_TRACE(ah->ah_sc);
-+
-+ tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
-+ tx_status = &desc->ud.ds_tx5210.tx_stat;
-
- /* No frame has been send or error */
- if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
-@@ -3810,32 +3939,32 @@
- /*
- * Get descriptor status
- */
-- desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
-+ ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
- AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
-- desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
-+ ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
- AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
-- desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
-+ ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
- AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
-- /*TODO: desc->ds_us.tx.ts_virtcol + test*/
-- desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
-+ /*TODO: ts->ts_virtcol + test*/
-+ ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
- AR5K_DESC_TX_STATUS1_SEQ_NUM);
-- desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
-+ ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
- AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
-- desc->ds_us.tx.ts_antenna = 1;
-- desc->ds_us.tx.ts_status = 0;
-- desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_0,
-+ ts->ts_antenna = 1;
-+ ts->ts_status = 0;
-+ ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
- AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
-
- if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
- if (tx_status->tx_status_0 &
- AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
-- desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY;
-+ ts->ts_status |= AR5K_TXERR_XRETRY;
-
- if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
-- desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO;
-+ ts->ts_status |= AR5K_TXERR_FIFO;
-
- if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
-- desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT;
-+ ts->ts_status |= AR5K_TXERR_FILT;
- }
-
- return 0;
-@@ -3845,14 +3974,15 @@
- * Proccess a tx descriptor on 5212
- */
- static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
-- struct ath5k_desc *desc)
-+ struct ath5k_desc *desc, struct ath5k_tx_status *ts)
- {
-+ struct ath5k_hw_4w_tx_ctl *tx_ctl;
- struct ath5k_hw_tx_status *tx_status;
-- struct ath5k_hw_4w_tx_desc *tx_desc;
-
- ATH5K_TRACE(ah->ah_sc);
-- tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
-- tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2];
-+
-+ tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
-+ tx_status = &desc->ud.ds_tx5212.tx_stat;
-
- /* No frame has been send or error */
- if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
-@@ -3861,42 +3991,42 @@
- /*
- * Get descriptor status
- */
-- desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
-+ ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
- AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
-- desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
-+ ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
- AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
-- desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
-+ ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
- AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
-- desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
-+ ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
- AR5K_DESC_TX_STATUS1_SEQ_NUM);
-- desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
-+ ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
- AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
-- desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 &
-+ ts->ts_antenna = (tx_status->tx_status_1 &
- AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
-- desc->ds_us.tx.ts_status = 0;
-+ ts->ts_status = 0;
-
- switch (AR5K_REG_MS(tx_status->tx_status_1,
- AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
- case 0:
-- desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 &
-+ ts->ts_rate = tx_ctl->tx_control_3 &
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
- break;
- case 1:
-- desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3,
-+ ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
-- desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2,
-+ ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
- break;
- case 2:
-- desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3,
-+ ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
-- desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2,
-+ ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
- break;
- case 3:
-- desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3,
-+ ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
-- desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2,
-+ ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
- break;
- }
-@@ -3904,13 +4034,13 @@
- if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
- if (tx_status->tx_status_0 &
- AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
-- desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY;
-+ ts->ts_status |= AR5K_TXERR_XRETRY;
-
- if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
-- desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO;
-+ ts->ts_status |= AR5K_TXERR_FIFO;
-
- if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
-- desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT;
-+ ts->ts_status |= AR5K_TXERR_FILT;
- }
-
- return 0;
-@@ -3926,31 +4056,27 @@
- int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
- u32 size, unsigned int flags)
- {
-- struct ath5k_rx_desc *rx_desc;
-+ struct ath5k_hw_rx_ctl *rx_ctl;
-
- ATH5K_TRACE(ah->ah_sc);
-- rx_desc = (struct ath5k_rx_desc *)&desc->ds_ctl0;
-+ rx_ctl = &desc->ud.ds_rx.rx_ctl;
-
- /*
-- *Clear ds_hw
-+ * Clear the descriptor
- * If we don't clean the status descriptor,
- * while scanning we get too many results,
- * most of them virtual, after some secs
- * of scanning system hangs. M.F.
- */
-- memset(desc->ds_hw, 0, sizeof(desc->ds_hw));
--
-- /*Initialize rx descriptor*/
-- rx_desc->rx_control_0 = 0;
-- rx_desc->rx_control_1 = 0;
-+ memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
-
- /* Setup descriptor */
-- rx_desc->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
-- if (unlikely(rx_desc->rx_control_1 != size))
-+ rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
-+ if (unlikely(rx_ctl->rx_control_1 != size))
- return -EINVAL;
-
- if (flags & AR5K_RXDESC_INTREQ)
-- rx_desc->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
-+ rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
-
- return 0;
- }
-@@ -3958,67 +4084,68 @@
- /*
- * Proccess the rx status descriptor on 5210/5211
- */
--static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *ah,
-- struct ath5k_desc *desc)
-+static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
-+ struct ath5k_desc *desc, struct ath5k_rx_status *rs)
- {
-- struct ath5k_hw_old_rx_status *rx_status;
-+ struct ath5k_hw_rx_status *rx_status;
-
-- rx_status = (struct ath5k_hw_old_rx_status *)&desc->ds_hw[0];
-+ rx_status = &desc->ud.ds_rx.u.rx_stat;
-
- /* No frame received / not ready */
-- if (unlikely((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_DONE)
-+ if (unlikely((rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DONE)
- == 0))
- return -EINPROGRESS;
-
- /*
- * Frame receive status
- */
-- desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
-- AR5K_OLD_RX_DESC_STATUS0_DATA_LEN;
-- desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
-- AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL);
-- desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
-- AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE);
-- desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
-- AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA;
-- desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
-- AR5K_OLD_RX_DESC_STATUS0_MORE;
-- desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
-- AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
-- desc->ds_us.rx.rs_status = 0;
-+ rs->rs_datalen = rx_status->rx_status_0 &
-+ AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
-+ rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
-+ AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
-+ rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
-+ AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
-+ rs->rs_antenna = rx_status->rx_status_0 &
-+ AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA;
-+ rs->rs_more = rx_status->rx_status_0 &
-+ AR5K_5210_RX_DESC_STATUS0_MORE;
-+ /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
-+ rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
-+ AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
-+ rs->rs_status = 0;
-
- /*
- * Key table status
- */
-- if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID)
-- desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
-- AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX);
-+ if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
-+ rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
-+ AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
- else
-- desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID;
-+ rs->rs_keyix = AR5K_RXKEYIX_INVALID;
-
- /*
- * Receive/descriptor errors
- */
-- if ((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK)
-- == 0) {
-- if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR)
-- desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC;
-+ if ((rx_status->rx_status_1 &
-+ AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
-+ if (rx_status->rx_status_1 &
-+ AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
-+ rs->rs_status |= AR5K_RXERR_CRC;
-
- if (rx_status->rx_status_1 &
-- AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN)
-- desc->ds_us.rx.rs_status |= AR5K_RXERR_FIFO;
-+ AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
-+ rs->rs_status |= AR5K_RXERR_FIFO;
-
- if (rx_status->rx_status_1 &
-- AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR) {
-- desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY;
-- desc->ds_us.rx.rs_phyerr =
-- AR5K_REG_MS(rx_status->rx_status_1,
-- AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR);
-+ AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
-+ rs->rs_status |= AR5K_RXERR_PHY;
-+ rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,
-+ AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
- }
-
- if (rx_status->rx_status_1 &
-- AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
-- desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT;
-+ AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
-+ rs->rs_status |= AR5K_RXERR_DECRYPT;
- }
-
- return 0;
-@@ -4027,71 +4154,72 @@
- /*
- * Proccess the rx status descriptor on 5212
- */
--static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *ah,
-- struct ath5k_desc *desc)
-+static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
-+ struct ath5k_desc *desc, struct ath5k_rx_status *rs)
- {
-- struct ath5k_hw_new_rx_status *rx_status;
-+ struct ath5k_hw_rx_status *rx_status;
- struct ath5k_hw_rx_error *rx_err;
-
- ATH5K_TRACE(ah->ah_sc);
-- rx_status = (struct ath5k_hw_new_rx_status *)&desc->ds_hw[0];
-+ rx_status = &desc->ud.ds_rx.u.rx_stat;
-
- /* Overlay on error */
-- rx_err = (struct ath5k_hw_rx_error *)&desc->ds_hw[0];
-+ rx_err = &desc->ud.ds_rx.u.rx_err;
-
- /* No frame received / not ready */
-- if (unlikely((rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_DONE)
-+ if (unlikely((rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DONE)
- == 0))
- return -EINPROGRESS;
-
- /*
- * Frame receive status
- */
-- desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
-- AR5K_NEW_RX_DESC_STATUS0_DATA_LEN;
-- desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
-- AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL);
-- desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
-- AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE);
-- desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
-- AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA;
-- desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
-- AR5K_NEW_RX_DESC_STATUS0_MORE;
-- desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
-- AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
-- desc->ds_us.rx.rs_status = 0;
-+ rs->rs_datalen = rx_status->rx_status_0 &
-+ AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
-+ rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
-+ AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
-+ rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
-+ AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
-+ rs->rs_antenna = rx_status->rx_status_0 &
-+ AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA;
-+ rs->rs_more = rx_status->rx_status_0 &
-+ AR5K_5212_RX_DESC_STATUS0_MORE;
-+ rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
-+ AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
-+ rs->rs_status = 0;
-
- /*
- * Key table status
- */
-- if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID)
-- desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
-- AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX);
-+ if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
-+ rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
-+ AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
- else
-- desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID;
-+ rs->rs_keyix = AR5K_RXKEYIX_INVALID;
-
- /*
- * Receive/descriptor errors
- */
- if ((rx_status->rx_status_1 &
-- AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
-- if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR)
-- desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC;
-+ AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
-+ if (rx_status->rx_status_1 &
-+ AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
-+ rs->rs_status |= AR5K_RXERR_CRC;
-
- if (rx_status->rx_status_1 &
-- AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR) {
-- desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY;
-- desc->ds_us.rx.rs_phyerr =
-- AR5K_REG_MS(rx_err->rx_error_1,
-+ AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
-+ rs->rs_status |= AR5K_RXERR_PHY;
-+ rs->rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1,
- AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
- }
-
- if (rx_status->rx_status_1 &
-- AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
-- desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT;
-+ AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
-+ rs->rs_status |= AR5K_RXERR_DECRYPT;
-
-- if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR)
-- desc->ds_us.rx.rs_status |= AR5K_RXERR_MIC;
-+ if (rx_status->rx_status_1 &
-+ AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
-+ rs->rs_status |= AR5K_RXERR_MIC;
- }
-
- return 0;
-@@ -4250,35 +4378,6 @@
- }
-
-
--/*********************************\
-- Regulatory Domain/Channels Setup
--\*********************************/
--
--u16 ath5k_get_regdomain(struct ath5k_hw *ah)
--{
-- u16 regdomain;
-- enum ath5k_regdom ieee_regdomain;
--#ifdef COUNTRYCODE
-- u16 code;
--#endif
--
-- ath5k_eeprom_regulation_domain(ah, false, &ieee_regdomain);
-- ah->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain;
--
--#ifdef COUNTRYCODE
-- /*
-- * Get the regulation domain by country code. This will ignore
-- * the settings found in the EEPROM.
-- */
-- code = ieee80211_name2countrycode(COUNTRYCODE);
-- ieee_regdomain = ieee80211_countrycode2regdomain(code);
--#endif
--
-- regdomain = ath5k_regdom_from_ieee(ieee_regdomain);
-- ah->ah_capabilities.cap_regdomain.reg_current = regdomain;
--
-- return regdomain;
--}
-
-
- /****************\
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/hw.h linux-2.6.25/drivers/net/wireless/ath5k/hw.h
---- linux-2.6.25.old/drivers/net/wireless/ath5k/hw.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/hw.h 2008-04-19 13:54:59.000000000 +0200
-@@ -173,7 +173,10 @@
- * (rX: reserved fields possibily used by future versions of the ar5k chipset)
- */
-
--struct ath5k_rx_desc {
-+/*
-+ * common hardware RX control descriptor
-+ */
-+struct ath5k_hw_rx_ctl {
- u32 rx_control_0; /* RX control word 0 */
-
- #define AR5K_DESC_RX_CTL0 0x00000000
-@@ -185,69 +188,63 @@
- } __packed;
-
- /*
-- * 5210/5211 rx status descriptor
-+ * common hardware RX status descriptor
-+ * 5210/11 and 5212 differ only in the flags defined below
- */
--struct ath5k_hw_old_rx_status {
-+struct ath5k_hw_rx_status {
- u32 rx_status_0; /* RX status word 0 */
--
--#define AR5K_OLD_RX_DESC_STATUS0_DATA_LEN 0x00000fff
--#define AR5K_OLD_RX_DESC_STATUS0_MORE 0x00001000
--#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000
--#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE_S 15
--#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000
--#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19
--#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000
--#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27
--
- u32 rx_status_1; /* RX status word 1 */
--
--#define AR5K_OLD_RX_DESC_STATUS1_DONE 0x00000001
--#define AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
--#define AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR 0x00000004
--#define AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008
--#define AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010
--#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR 0x000000e0
--#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR_S 5
--#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
--#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX 0x00007e00
--#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_S 9
--#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000
--#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15
--#define AR5K_OLD_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000
- } __packed;
-
-+/* 5210/5211 */
-+#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff
-+#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000
-+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000
-+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S 15
-+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000
-+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19
-+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000
-+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27
-+#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001
-+#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
-+#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004
-+#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008
-+#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010
-+#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0
-+#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S 5
-+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
-+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00
-+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S 9
-+#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000
-+#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15
-+#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000
-+
-+/* 5212 */
-+#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff
-+#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000
-+#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000
-+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000
-+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S 15
-+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000
-+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20
-+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000
-+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28
-+#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001
-+#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
-+#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004
-+#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008
-+#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR 0x00000010
-+#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR 0x00000020
-+#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
-+#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00
-+#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S 9
-+#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000
-+#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16
-+#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000
-+
- /*
-- * 5212 rx status descriptor
-+ * common hardware RX error descriptor
- */
--struct ath5k_hw_new_rx_status {
-- u32 rx_status_0; /* RX status word 0 */
--
--#define AR5K_NEW_RX_DESC_STATUS0_DATA_LEN 0x00000fff
--#define AR5K_NEW_RX_DESC_STATUS0_MORE 0x00001000
--#define AR5K_NEW_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000
--#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000
--#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE_S 15
--#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000
--#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20
--#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000
--#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28
--
-- u32 rx_status_1; /* RX status word 1 */
--
--#define AR5K_NEW_RX_DESC_STATUS1_DONE 0x00000001
--#define AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
--#define AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR 0x00000004
--#define AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008
--#define AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR 0x00000010
--#define AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR 0x00000020
--#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
--#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00
--#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_S 9
--#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000
--#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16
--#define AR5K_NEW_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000
--} __packed;
--
- struct ath5k_hw_rx_error {
- u32 rx_error_0; /* RX error word 0 */
-
-@@ -268,7 +265,10 @@
- #define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0
- #define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0
-
--struct ath5k_hw_2w_tx_desc {
-+/*
-+ * 5210/5211 hardware 2-word TX control descriptor
-+ */
-+struct ath5k_hw_2w_tx_ctl {
- u32 tx_control_0; /* TX control word 0 */
-
- #define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff
-@@ -314,9 +314,9 @@
- #define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 0x10
-
- /*
-- * 5212 4-word tx control descriptor
-+ * 5212 hardware 4-word TX control descriptor
- */
--struct ath5k_hw_4w_tx_desc {
-+struct ath5k_hw_4w_tx_ctl {
- u32 tx_control_0; /* TX control word 0 */
-
- #define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff
-@@ -374,7 +374,7 @@
- } __packed;
-
- /*
-- * Common tx status descriptor
-+ * Common TX status descriptor
- */
- struct ath5k_hw_tx_status {
- u32 tx_status_0; /* TX status word 0 */
-@@ -415,6 +415,34 @@
-
-
- /*
-+ * 5210/5211 hardware TX descriptor
-+ */
-+struct ath5k_hw_5210_tx_desc {
-+ struct ath5k_hw_2w_tx_ctl tx_ctl;
-+ struct ath5k_hw_tx_status tx_stat;
-+} __packed;
-+
-+/*
-+ * 5212 hardware TX descriptor
-+ */
-+struct ath5k_hw_5212_tx_desc {
-+ struct ath5k_hw_4w_tx_ctl tx_ctl;
-+ struct ath5k_hw_tx_status tx_stat;
-+} __packed;
-+
-+/*
-+ * common hardware RX descriptor
-+ */
-+struct ath5k_hw_all_rx_desc {
-+ struct ath5k_hw_rx_ctl rx_ctl;
-+ union {
-+ struct ath5k_hw_rx_status rx_stat;
-+ struct ath5k_hw_rx_error rx_err;
-+ } u;
-+} __packed;
-+
-+
-+/*
- * AR5K REGISTER ACCESS
- */
-
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/initvals.c linux-2.6.25/drivers/net/wireless/ath5k/initvals.c
---- linux-2.6.25.old/drivers/net/wireless/ath5k/initvals.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/initvals.c 2008-04-19 13:54:59.000000000 +0200
-@@ -678,8 +678,8 @@
- { AR5K_PHY(644), 0x00806333 },
- { AR5K_PHY(645), 0x00106c10 },
- { AR5K_PHY(646), 0x009c4060 },
-- /*{ AR5K_PHY(647), 0x1483800a },*/ /* Old value */
- { AR5K_PHY(647), 0x1483800a },
-+ /* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413 */
- { AR5K_PHY(648), 0x01831061 },
- { AR5K_PHY(649), 0x00000400 },
- /*{ AR5K_PHY(650), 0x000001b5 },*/
-@@ -1081,6 +1081,414 @@
- { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
- };
-
-+/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
-+/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
-+ * minor tweaking based on dumps from other chips */
-+static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
-+ { AR5K_TXCFG,
-+ /* b g gTurbo */
-+ { 0x00000015, 0x00000015, 0x00000015 } },
-+ { AR5K_USEC_5211,
-+ { 0x04e01395, 0x12e013ab, 0x098813cf } },
-+ { AR5K_PHY(10),
-+ { 0x05020000, 0x0a020001, 0x0a020001 } },
-+ { AR5K_PHY(13),
-+ { 0x00000e00, 0x00000e00, 0x00000e00 } },
-+ { AR5K_PHY(14),
-+ { 0x0000000a, 0x0000000a, 0x0000000a } },
-+ { AR5K_PHY(18),
-+ { 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
-+ { AR5K_PHY(20),
-+ { 0x0de8b0da, 0x0c98b0da, 0x0c98b0da } },
-+ { AR5K_PHY_SIG,
-+ { 0x7ee80d2e, 0x7ec80d2e, 0x7ec80d2e } },
-+ { AR5K_PHY_AGCCOARSE,
-+ { 0x3137665e, 0x3139605e, 0x3139605e } },
-+ { AR5K_PHY(27),
-+ { 0x050cb081, 0x050cb081, 0x050cb081 } },
-+ { AR5K_PHY_RX_DELAY,
-+ { 0x0000044c, 0x00000898, 0x000007d0 } },
-+ { AR5K_PHY_FRAME_CTL_5211,
-+ { 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
-+ { AR5K_PHY_CCKTXCTL,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(642),
-+ { 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-+ { AR5K_PHY_GAIN_2GHZ,
-+ { 0x0042c140, 0x0042c140, 0x0042c140 } },
-+ { 0xa21c,
-+ { 0x1863800a, 0x1883800a, 0x1883800a } },
-+ { AR5K_DCU_FP,
-+ { 0x000003e0, 0x000003e0, 0x000003e0 } },
-+ { 0x8060,
-+ { 0x0000000f, 0x0000000f, 0x0000000f } },
-+ { 0x8118,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x811c,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x8120,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x8124,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x8128,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x812c,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x8130,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x8134,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x8138,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x813c,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0x8140,
-+ { 0x800000a8, 0x800000a8, 0x800000a8 } },
-+ { 0x8144,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { AR5K_PHY_AGC,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(11),
-+ { 0x0000a000, 0x0000a000, 0x0000a000 } },
-+ { AR5K_PHY(15),
-+ { 0x00200400, 0x00200400, 0x00200400 } },
-+ { AR5K_PHY(19),
-+ { 0x1284233c, 0x1284233c, 0x1284233c } },
-+ { AR5K_PHY_SCR,
-+ { 0x0000001f, 0x0000001f, 0x0000001f } },
-+ { AR5K_PHY_SLMT,
-+ { 0x00000080, 0x00000080, 0x00000080 } },
-+ { AR5K_PHY_SCAL,
-+ { 0x0000000e, 0x0000000e, 0x0000000e } },
-+ { AR5K_PHY(86),
-+ { 0x000000ff, 0x000000ff, 0x000000ff } },
-+ { AR5K_PHY(96),
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(97),
-+ { 0x02800000, 0x02800000, 0x02800000 } },
-+ { AR5K_PHY(104),
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(120),
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(121),
-+ { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
-+ { AR5K_PHY(122),
-+ { 0x3c466478, 0x3c466478, 0x3c466478 } },
-+ { AR5K_PHY(123),
-+ { 0x000000aa, 0x000000aa, 0x000000aa } },
-+ { AR5K_PHY_SCLOCK,
-+ { 0x0000000c, 0x0000000c, 0x0000000c } },
-+ { AR5K_PHY_SDELAY,
-+ { 0x000000ff, 0x000000ff, 0x000000ff } },
-+ { AR5K_PHY_SPENDING,
-+ { 0x00000014, 0x00000014, 0x00000014 } },
-+ { 0xa228,
-+ { 0x000009b5, 0x000009b5, 0x000009b5 } },
-+ { 0xa23c,
-+ { 0x93c889af, 0x93c889af, 0x93c889af } },
-+ { 0xa24c,
-+ { 0x00000001, 0x00000001, 0x00000001 } },
-+ { 0xa250,
-+ { 0x0000a000, 0x0000a000, 0x0000a000 } },
-+ { 0xa254,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0xa258,
-+ { 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
-+ { 0xa25c,
-+ { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
-+ { 0xa260,
-+ { 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
-+ { 0xa264,
-+ { 0x00418a11, 0x00418a11, 0x00418a11 } },
-+ { 0xa268,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0xa26c,
-+ { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
-+ { 0xa270,
-+ { 0x00820820, 0x00820820, 0x00820820 } },
-+ { 0xa274,
-+ { 0x001b7caa, 0x001b7caa, 0x001b7caa } },
-+ { 0xa278,
-+ { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
-+ { 0xa27c,
-+ { 0x051701ce, 0x051701ce, 0x051701ce } },
-+ { 0xa300,
-+ { 0x18010000, 0x18010000, 0x18010000 } },
-+ { 0xa304,
-+ { 0x30032602, 0x30032602, 0x30032602 } },
-+ { 0xa308,
-+ { 0x48073e06, 0x48073e06, 0x48073e06 } },
-+ { 0xa30c,
-+ { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
-+ { 0xa310,
-+ { 0x641a600f, 0x641a600f, 0x641a600f } },
-+ { 0xa314,
-+ { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
-+ { 0xa318,
-+ { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
-+ { 0xa31c,
-+ { 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
-+ { 0xa320,
-+ { 0x9d4f970f, 0x9d4f970f, 0x9d4f970f } },
-+ { 0xa324,
-+ { 0xa5cfa18f, 0xa5cfa18f, 0xa5cfa18f } },
-+ { 0xa328,
-+ { 0xb55faf1f, 0xb55faf1f, 0xb55faf1f } },
-+ { 0xa32c,
-+ { 0xbddfb99f, 0xbddfb99f, 0xbddfb99f } },
-+ { 0xa330,
-+ { 0xcd7fc73f, 0xcd7fc73f, 0xcd7fc73f } },
-+ { 0xa334,
-+ { 0xd5ffd1bf, 0xd5ffd1bf, 0xd5ffd1bf } },
-+ { 0xa338,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0xa33c,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0xa340,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0xa344,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 0xa348,
-+ { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
-+ { 0xa34c,
-+ { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
-+ { 0xa350,
-+ { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
-+ { 0xa354,
-+ { 0x0003ffff, 0x0003ffff, 0x0003ffff } },
-+ { 0xa358,
-+ { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
-+ { 0xa35c,
-+ { 0x066c420f, 0x066c420f, 0x066c420f } },
-+ { 0xa360,
-+ { 0x0f282207, 0x0f282207, 0x0f282207 } },
-+ { 0xa364,
-+ { 0x17601685, 0x17601685, 0x17601685 } },
-+ { 0xa368,
-+ { 0x1f801104, 0x1f801104, 0x1f801104 } },
-+ { 0xa36c,
-+ { 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
-+ { 0xa370,
-+ { 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
-+ { 0xa374,
-+ { 0x57c00803, 0x57c00803, 0x57c00803 } },
-+ { 0xa378,
-+ { 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
-+ { 0xa37c,
-+ { 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
-+ { 0xa380,
-+ { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
-+ { 0xa384,
-+ { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
-+};
-+
-+/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */
-+/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
-+ * minor tweaking based on dumps from other chips */
-+static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
-+ { AR5K_TXCFG,
-+ /* g gTurbo */
-+ { 0x00000015, 0x00000015 } },
-+ { AR5K_USEC_5211,
-+ { 0x12e013ab, 0x098813cf } },
-+ { AR5K_PHY_TURBO,
-+ { 0x00000000, 0x00000003 } },
-+ { AR5K_PHY(10),
-+ { 0x0a020001, 0x0a020001 } },
-+ { AR5K_PHY(13),
-+ { 0x00000e0e, 0x00000e0e } },
-+ { AR5K_PHY(14),
-+ { 0x0000000b, 0x0000000b } },
-+ { AR5K_PHY(17),
-+ { 0x13721422, 0x13721422 } },
-+ { AR5K_PHY(18),
-+ { 0x00199a65, 0x00199a65 } },
-+ { AR5K_PHY(20),
-+ { 0x0c98b0da, 0x0c98b0da } },
-+ { AR5K_PHY_SIG,
-+ { 0x7ec80d2e, 0x7ec80d2e } },
-+ { AR5K_PHY_AGCCOARSE,
-+ { 0x3139605e, 0x3139605e } },
-+ { AR5K_PHY(27),
-+ { 0x050cb081, 0x050cb081 } },
-+ { AR5K_PHY_RX_DELAY,
-+ { 0x00000898, 0x000007d0 } },
-+ { AR5K_PHY_FRAME_CTL_5211,
-+ { 0xf7b81000, 0xf7b81000 } },
-+ { AR5K_PHY_CCKTXCTL,
-+ { 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(642),
-+ { 0xd03e6788, 0xd03e6788 } },
-+ { AR5K_PHY_GAIN_2GHZ,
-+ { 0x0052c140, 0x0052c140 } },
-+ { 0xa21c,
-+ { 0x1883800a, 0x1883800a } },
-+ { 0xa324,
-+ { 0xa7cfa7cf, 0xa7cfa7cf } },
-+ { 0xa328,
-+ { 0xa7cfa7cf, 0xa7cfa7cf } },
-+ { 0xa32c,
-+ { 0xa7cfa7cf, 0xa7cfa7cf } },
-+ { 0xa330,
-+ { 0xa7cfa7cf, 0xa7cfa7cf } },
-+ { 0xa334,
-+ { 0xa7cfa7cf, 0xa7cfa7cf } },
-+ { AR5K_DCU_FP,
-+ { 0x000003e0, 0x000003e0 } },
-+ { 0x8060,
-+ { 0x0000000f, 0x0000000f } },
-+ { 0x809c,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x80a0,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x8118,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x811c,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x8120,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x8124,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x8128,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x812c,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x8130,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x8134,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x8138,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x813c,
-+ { 0x00000000, 0x00000000 } },
-+ { 0x8140,
-+ { 0x800003f9, 0x800003f9 } },
-+ { 0x8144,
-+ { 0x00000000, 0x00000000 } },
-+ { AR5K_PHY_AGC,
-+ { 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(11),
-+ { 0x0000a000, 0x0000a000 } },
-+ { AR5K_PHY(15),
-+ { 0x00200400, 0x00200400 } },
-+ { AR5K_PHY(19),
-+ { 0x1284233c, 0x1284233c } },
-+ { AR5K_PHY_SCR,
-+ { 0x0000001f, 0x0000001f } },
-+ { AR5K_PHY_SLMT,
-+ { 0x00000080, 0x00000080 } },
-+ { AR5K_PHY_SCAL,
-+ { 0x0000000e, 0x0000000e } },
-+ { AR5K_PHY(86),
-+ { 0x00081fff, 0x00081fff } },
-+ { AR5K_PHY(96),
-+ { 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(97),
-+ { 0x02800000, 0x02800000 } },
-+ { AR5K_PHY(104),
-+ { 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(119),
-+ { 0xfebadbe8, 0xfebadbe8 } },
-+ { AR5K_PHY(120),
-+ { 0x00000000, 0x00000000 } },
-+ { AR5K_PHY(121),
-+ { 0xaaaaaaaa, 0xaaaaaaaa } },
-+ { AR5K_PHY(122),
-+ { 0x3c466478, 0x3c466478 } },
-+ { AR5K_PHY(123),
-+ { 0x000000aa, 0x000000aa } },
-+ { AR5K_PHY_SCLOCK,
-+ { 0x0000000c, 0x0000000c } },
-+ { AR5K_PHY_SDELAY,
-+ { 0x000000ff, 0x000000ff } },
-+ { AR5K_PHY_SPENDING,
-+ { 0x00000014, 0x00000014 } },
-+ { 0xa228,
-+ { 0x000009b5, 0x000009b5 } },
-+ { AR5K_PHY_TXPOWER_RATE3,
-+ { 0x20202020, 0x20202020 } },
-+ { AR5K_PHY_TXPOWER_RATE4,
-+ { 0x20202020, 0x20202020 } },
-+ { 0xa23c,
-+ { 0x93c889af, 0x93c889af } },
-+ { 0xa24c,
-+ { 0x00000001, 0x00000001 } },
-+ { 0xa250,
-+ { 0x0000a000, 0x0000a000 } },
-+ { 0xa254,
-+ { 0x00000000, 0x00000000 } },
-+ { 0xa258,
-+ { 0x0cc75380, 0x0cc75380 } },
-+ { 0xa25c,
-+ { 0x0f0f0f01, 0x0f0f0f01 } },
-+ { 0xa260,
-+ { 0x5f690f01, 0x5f690f01 } },
-+ { 0xa264,
-+ { 0x00418a11, 0x00418a11 } },
-+ { 0xa268,
-+ { 0x00000000, 0x00000000 } },
-+ { 0xa26c,
-+ { 0x0c30c166, 0x0c30c166 } },
-+ { 0xa270,
-+ { 0x00820820, 0x00820820 } },
-+ { 0xa274,
-+ { 0x081a3caa, 0x081a3caa } },
-+ { 0xa278,
-+ { 0x1ce739ce, 0x1ce739ce } },
-+ { 0xa27c,
-+ { 0x051701ce, 0x051701ce } },
-+ { 0xa300,
-+ { 0x16010000, 0x16010000 } },
-+ { 0xa304,
-+ { 0x2c032402, 0x2c032402 } },
-+ { 0xa308,
-+ { 0x48433e42, 0x48433e42 } },
-+ { 0xa30c,
-+ { 0x5a0f500b, 0x5a0f500b } },
-+ { 0xa310,
-+ { 0x6c4b624a, 0x6c4b624a } },
-+ { 0xa314,
-+ { 0x7e8b748a, 0x7e8b748a } },
-+ { 0xa318,
-+ { 0x96cf8ccb, 0x96cf8ccb } },
-+ { 0xa31c,
-+ { 0xa34f9d0f, 0xa34f9d0f } },
-+ { 0xa320,
-+ { 0xa7cfa58f, 0xa7cfa58f } },
-+ { 0xa348,
-+ { 0x3fffffff, 0x3fffffff } },
-+ { 0xa34c,
-+ { 0x3fffffff, 0x3fffffff } },
-+ { 0xa350,
-+ { 0x3fffffff, 0x3fffffff } },
-+ { 0xa354,
-+ { 0x0003ffff, 0x0003ffff } },
-+ { 0xa358,
-+ { 0x79a8aa1f, 0x79a8aa1f } },
-+ { 0xa35c,
-+ { 0x066c420f, 0x066c420f } },
-+ { 0xa360,
-+ { 0x0f282207, 0x0f282207 } },
-+ { 0xa364,
-+ { 0x17601685, 0x17601685 } },
-+ { 0xa368,
-+ { 0x1f801104, 0x1f801104 } },
-+ { 0xa36c,
-+ { 0x37a00c03, 0x37a00c03 } },
-+ { 0xa370,
-+ { 0x3fc40883, 0x3fc40883 } },
-+ { 0xa374,
-+ { 0x57c00803, 0x57c00803 } },
-+ { 0xa378,
-+ { 0x5fd80682, 0x5fd80682 } },
-+ { 0xa37c,
-+ { 0x7fe00482, 0x7fe00482 } },
-+ { 0xa380,
-+ { 0x7f3c7bba, 0x7f3c7bba } },
-+ { 0xa384,
-+ { 0xf3307ff0, 0xf3307ff0 } },
-+};
-+
- /*
- * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with
- * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI)
-@@ -1290,35 +1698,92 @@
-
- /* Second set of mode-specific settings */
- if (ah->ah_radio == AR5K_RF5111){
-+
- ath5k_hw_ini_mode_registers(ah,
- ARRAY_SIZE(ar5212_rf5111_ini_mode_end),
- ar5212_rf5111_ini_mode_end, mode);
-+
- /* Baseband gain table */
- ath5k_hw_ini_registers(ah,
- ARRAY_SIZE(rf5111_ini_bbgain),
- rf5111_ini_bbgain, change_channel);
-+
- } else if (ah->ah_radio == AR5K_RF5112){
-+
- ath5k_hw_ini_mode_registers(ah,
- ARRAY_SIZE(ar5212_rf5112_ini_mode_end),
- ar5212_rf5112_ini_mode_end, mode);
-- /* Baseband gain table */
-+
- ath5k_hw_ini_registers(ah,
- ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
-+
- } else if (ah->ah_radio == AR5K_RF5413){
-+
- ath5k_hw_ini_mode_registers(ah,
- ARRAY_SIZE(rf5413_ini_mode_end),
- rf5413_ini_mode_end, mode);
-+
-+ ath5k_hw_ini_registers(ah,
-+ ARRAY_SIZE(rf5112_ini_bbgain),
-+ rf5112_ini_bbgain, change_channel);
-+
-+ } else if (ah->ah_radio == AR5K_RF2413) {
-+
-+ if (mode < 2) {
-+ ATH5K_ERR(ah->ah_sc,
-+ "unsupported channel mode: %d\n", mode);
-+ return -EINVAL;
-+ }
-+ mode = mode - 2;
-+
-+ /* Override a setting from ar5212_ini */
-+ ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
-+
-+ ath5k_hw_ini_mode_registers(ah,
-+ ARRAY_SIZE(rf2413_ini_mode_end),
-+ rf2413_ini_mode_end, mode);
-+
- /* Baseband gain table */
- ath5k_hw_ini_registers(ah,
- ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
-+
-+ } else if (ah->ah_radio == AR5K_RF2425) {
-+
-+ if (mode < 2) {
-+ ATH5K_ERR(ah->ah_sc,
-+ "unsupported channel mode: %d\n", mode);
-+ return -EINVAL;
-+ }
-+
-+ /* Map b to g */
-+ if (mode == 2)
-+ mode = 0;
-+ else
-+ mode = mode - 3;
-+
-+ /* Override a setting from ar5212_ini */
-+ ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
-+
-+ ath5k_hw_ini_mode_registers(ah,
-+ ARRAY_SIZE(rf2425_ini_mode_end),
-+ rf2425_ini_mode_end, mode);
-+
-+ /* Baseband gain table */
-+ ath5k_hw_ini_registers(ah,
-+ ARRAY_SIZE(rf5112_ini_bbgain),
-+ rf5112_ini_bbgain, change_channel);
-+
- }
-+
- /* For AR5211 */
- } else if (ah->ah_version == AR5K_AR5211) {
-
-- if(mode > 2){ /* AR5K_INI_VAL_11B */
-- ATH5K_ERR(ah->ah_sc,"unsupported channel mode: %d\n", mode);
-+ /* AR5K_MODE_11B */
-+ if (mode > 2) {
-+ ATH5K_ERR(ah->ah_sc,
-+ "unsupported channel mode: %d\n", mode);
- return -EINVAL;
- }
-
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/Kconfig linux-2.6.25/drivers/net/wireless/ath5k/Kconfig
---- linux-2.6.25.old/drivers/net/wireless/ath5k/Kconfig 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.25/drivers/net/wireless/ath5k/Kconfig 2008-04-19 13:54:59.000000000 +0200
-@@ -0,0 +1,37 @@
-+config ATH5K
-+ tristate "Atheros 5xxx wireless cards support"
-+ depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
-+ ---help---
-+ This module adds support for wireless adapters based on
-+ Atheros 5xxx chipset.
-+
-+ Currently the following chip versions are supported:
-+
-+ MAC: AR5211 AR5212
-+ PHY: RF5111/2111 RF5112/2112 RF5413/2413
-+
-+ This driver uses the kernel's mac80211 subsystem.
-+
-+ If you choose to build a module, it'll be called ath5k. Say M if
-+ unsure.
-+
-+config ATH5K_DEBUG
-+ bool "Atheros 5xxx debugging"
-+ depends on ATH5K
-+ ---help---
-+ Atheros 5xxx debugging messages.
-+
-+ Say Y, if and you will get debug options for ath5k.
-+ To use this, you need to mount debugfs:
-+
-+ mkdir /debug/
-+ mount -t debugfs debug /debug/
-+
-+ You will get access to files under:
-+ /debug/ath5k/phy0/
-+
-+ To enable debug, pass the debug level to the debug module
-+ parameter. For example:
-+
-+ modprobe ath5k debug=0x00000400
-+
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/Makefile linux-2.6.25/drivers/net/wireless/ath5k/Makefile
---- linux-2.6.25.old/drivers/net/wireless/ath5k/Makefile 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/Makefile 2008-04-19 13:54:59.000000000 +0200
-@@ -1,2 +1,6 @@
--ath5k-objs = base.o hw.o regdom.o initvals.o phy.o debug.o
-+ath5k-y += base.o
-+ath5k-y += hw.o
-+ath5k-y += initvals.o
-+ath5k-y += phy.o
-+ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
- obj-$(CONFIG_ATH5K) += ath5k.o
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/phy.c linux-2.6.25/drivers/net/wireless/ath5k/phy.c
---- linux-2.6.25.old/drivers/net/wireless/ath5k/phy.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/phy.c 2008-04-19 13:54:59.000000000 +0200
-@@ -666,6 +666,153 @@
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
- };
-
-+/* RF2413/2414 mode-specific init registers */
-+static const struct ath5k_ini_rf rfregs_2413[] = {
-+ { 1, AR5K_RF_BUFFER_CONTROL_4,
-+ /* mode b mode g mode gTurbo */
-+ { 0x00000020, 0x00000020, 0x00000020 } },
-+ { 2, AR5K_RF_BUFFER_CONTROL_3,
-+ { 0x02001408, 0x02001408, 0x02001408 } },
-+ { 3, AR5K_RF_BUFFER_CONTROL_6,
-+ { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0xf0000000, 0xf0000000, 0xf0000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x03000000, 0x03000000, 0x03000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x40400000, 0x40400000, 0x40400000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x65050000, 0x65050000, 0x65050000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00420000, 0x00420000, 0x00420000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00b50000, 0x00b50000, 0x00b50000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00030000, 0x00030000, 0x00030000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00f70000, 0x00f70000, 0x00f70000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x009d0000, 0x009d0000, 0x009d0000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00220000, 0x00220000, 0x00220000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x04220000, 0x04220000, 0x04220000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00230018, 0x00230018, 0x00230018 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00280050, 0x00280050, 0x00280050 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x005000c3, 0x005000c3, 0x005000c3 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x0004007f, 0x0004007f, 0x0004007f } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000458, 0x00000458, 0x00000458 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x0000c000, 0x0000c000, 0x0000c000 } },
-+ { 6, AR5K_RF_BUFFER_CONTROL_5,
-+ { 0x00400230, 0x00400230, 0x00400230 } },
-+ { 7, AR5K_RF_BUFFER,
-+ { 0x00006400, 0x00006400, 0x00006400 } },
-+ { 7, AR5K_RF_BUFFER,
-+ { 0x00000800, 0x00000800, 0x00000800 } },
-+ { 7, AR5K_RF_BUFFER_CONTROL_2,
-+ { 0x0000000e, 0x0000000e, 0x0000000e } },
-+};
-+
-+/* RF2425 mode-specific init registers */
-+static const struct ath5k_ini_rf rfregs_2425[] = {
-+ { 1, AR5K_RF_BUFFER_CONTROL_4,
-+ /* mode g mode gTurbo */
-+ { 0x00000020, 0x00000020 } },
-+ { 2, AR5K_RF_BUFFER_CONTROL_3,
-+ { 0x02001408, 0x02001408 } },
-+ { 3, AR5K_RF_BUFFER_CONTROL_6,
-+ { 0x00e020c0, 0x00e020c0 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x10000000, 0x10000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x002a0000, 0x002a0000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00100000, 0x00100000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00020000, 0x00020000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00730000, 0x00730000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00f80000, 0x00f80000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00e70000, 0x00e70000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00140000, 0x00140000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00910040, 0x00910040 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x0007001a, 0x0007001a } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00410000, 0x00410000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00810060, 0x00810060 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00020803, 0x00020803 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00000000, 0x00000000 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00001660, 0x00001660 } },
-+ { 6, AR5K_RF_BUFFER,
-+ { 0x00001688, 0x00001688 } },
-+ { 6, AR5K_RF_BUFFER_CONTROL_1,
-+ { 0x00000001, 0x00000001 } },
-+ { 7, AR5K_RF_BUFFER,
-+ { 0x00006400, 0x00006400 } },
-+ { 7, AR5K_RF_BUFFER,
-+ { 0x00000800, 0x00000800 } },
-+ { 7, AR5K_RF_BUFFER_CONTROL_2,
-+ { 0x0000000e, 0x0000000e } },
-+};
-
- /* Initial RF Gain settings for RF5112 */
- static const struct ath5k_ini_rfgain rfgain_5112[] = {
-@@ -805,6 +952,74 @@
- { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } },
- };
-
-+/* Initial RF Gain settings for RF2413 */
-+static const struct ath5k_ini_rfgain rfgain_2413[] = {
-+ { AR5K_RF_GAIN(0), { 0x00000000 } },
-+ { AR5K_RF_GAIN(1), { 0x00000040 } },
-+ { AR5K_RF_GAIN(2), { 0x00000080 } },
-+ { AR5K_RF_GAIN(3), { 0x00000181 } },
-+ { AR5K_RF_GAIN(4), { 0x000001c1 } },
-+ { AR5K_RF_GAIN(5), { 0x00000001 } },
-+ { AR5K_RF_GAIN(6), { 0x00000041 } },
-+ { AR5K_RF_GAIN(7), { 0x00000081 } },
-+ { AR5K_RF_GAIN(8), { 0x00000168 } },
-+ { AR5K_RF_GAIN(9), { 0x000001a8 } },
-+ { AR5K_RF_GAIN(10), { 0x000001e8 } },
-+ { AR5K_RF_GAIN(11), { 0x00000028 } },
-+ { AR5K_RF_GAIN(12), { 0x00000068 } },
-+ { AR5K_RF_GAIN(13), { 0x00000189 } },
-+ { AR5K_RF_GAIN(14), { 0x000001c9 } },
-+ { AR5K_RF_GAIN(15), { 0x00000009 } },
-+ { AR5K_RF_GAIN(16), { 0x00000049 } },
-+ { AR5K_RF_GAIN(17), { 0x00000089 } },
-+ { AR5K_RF_GAIN(18), { 0x00000190 } },
-+ { AR5K_RF_GAIN(19), { 0x000001d0 } },
-+ { AR5K_RF_GAIN(20), { 0x00000010 } },
-+ { AR5K_RF_GAIN(21), { 0x00000050 } },
-+ { AR5K_RF_GAIN(22), { 0x00000090 } },
-+ { AR5K_RF_GAIN(23), { 0x00000191 } },
-+ { AR5K_RF_GAIN(24), { 0x000001d1 } },
-+ { AR5K_RF_GAIN(25), { 0x00000011 } },
-+ { AR5K_RF_GAIN(26), { 0x00000051 } },
-+ { AR5K_RF_GAIN(27), { 0x00000091 } },
-+ { AR5K_RF_GAIN(28), { 0x00000178 } },
-+ { AR5K_RF_GAIN(29), { 0x000001b8 } },
-+ { AR5K_RF_GAIN(30), { 0x000001f8 } },
-+ { AR5K_RF_GAIN(31), { 0x00000038 } },
-+ { AR5K_RF_GAIN(32), { 0x00000078 } },
-+ { AR5K_RF_GAIN(33), { 0x00000199 } },
-+ { AR5K_RF_GAIN(34), { 0x000001d9 } },
-+ { AR5K_RF_GAIN(35), { 0x00000019 } },
-+ { AR5K_RF_GAIN(36), { 0x00000059 } },
-+ { AR5K_RF_GAIN(37), { 0x00000099 } },
-+ { AR5K_RF_GAIN(38), { 0x000000d9 } },
-+ { AR5K_RF_GAIN(39), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(40), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(41), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(42), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(43), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(44), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(45), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(46), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(47), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(48), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(49), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(50), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(51), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(52), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(53), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(54), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(55), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(56), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(57), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(58), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(59), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(60), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(61), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(62), { 0x000000f9 } },
-+ { AR5K_RF_GAIN(63), { 0x000000f9 } },
-+};
-+
- static const struct ath5k_gain_opt rfgain_opt_5112 = {
- 1,
- 8,
-@@ -844,14 +1059,14 @@
- entry = ((first - 1) / 8) + offset;
- position = (first - 1) % 8;
-
-- if (set == true)
-+ if (set)
- data = ath5k_hw_bitswap(reg, bits);
-
- for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
- last = (position + left > 8) ? 8 : position + left;
- mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8);
-
-- if (set == true) {
-+ if (set) {
- rf[entry] &= ~mask;
- rf[entry] |= ((data << position) << (col * 8)) & mask;
- data >>= (8 - position);
-@@ -864,7 +1079,7 @@
- left -= 8 - position;
- }
-
-- data = set == true ? 1 : ath5k_hw_bitswap(data, bits);
-+ data = set ? 1 : ath5k_hw_bitswap(data, bits);
-
- return data;
- }
-@@ -955,7 +1170,6 @@
- go = &rfgain_opt_5111;
- break;
- case AR5K_RF5112:
-- case AR5K_RF5413: /* ??? */
- go = &rfgain_opt_5112;
- break;
- default:
-@@ -1018,7 +1232,7 @@
- int obdb = -1, bank = -1;
- u32 ee_mode;
-
-- AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
-+ AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
-
- rf = ah->ah_rf_banks;
-
-@@ -1038,8 +1252,8 @@
- }
-
- /* Modify bank 0 */
-- if (channel->val & CHANNEL_2GHZ) {
-- if (channel->val & CHANNEL_CCK)
-+ if (channel->hw_value & CHANNEL_2GHZ) {
-+ if (channel->hw_value & CHANNEL_CCK)
- ee_mode = AR5K_EEPROM_MODE_11B;
- else
- ee_mode = AR5K_EEPROM_MODE_11G;
-@@ -1058,10 +1272,10 @@
- } else {
- /* For 11a, Turbo and XR */
- ee_mode = AR5K_EEPROM_MODE_11A;
-- obdb = channel->freq >= 5725 ? 3 :
-- (channel->freq >= 5500 ? 2 :
-- (channel->freq >= 5260 ? 1 :
-- (channel->freq > 4000 ? 0 : -1)));
-+ obdb = channel->center_freq >= 5725 ? 3 :
-+ (channel->center_freq >= 5500 ? 2 :
-+ (channel->center_freq >= 5260 ? 1 :
-+ (channel->center_freq > 4000 ? 0 : -1)));
-
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_pwd_84, 1, 51, 3, true))
-@@ -1119,12 +1333,12 @@
- int obdb = -1, bank = -1;
- u32 ee_mode;
-
-- AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
-+ AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
-
- rf = ah->ah_rf_banks;
-
- if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A
-- && !test_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode)){
-+ && !test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) {
- rf_ini = rfregs_2112a;
- rf_size = ARRAY_SIZE(rfregs_5112a);
- if (mode < 2) {
-@@ -1156,8 +1370,8 @@
- }
-
- /* Modify bank 6 */
-- if (channel->val & CHANNEL_2GHZ) {
-- if (channel->val & CHANNEL_OFDM)
-+ if (channel->hw_value & CHANNEL_2GHZ) {
-+ if (channel->hw_value & CHANNEL_OFDM)
- ee_mode = AR5K_EEPROM_MODE_11G;
- else
- ee_mode = AR5K_EEPROM_MODE_11B;
-@@ -1173,10 +1387,13 @@
- } else {
- /* For 11a, Turbo and XR */
- ee_mode = AR5K_EEPROM_MODE_11A;
-- obdb = channel->freq >= 5725 ? 3 :
-- (channel->freq >= 5500 ? 2 :
-- (channel->freq >= 5260 ? 1 :
-- (channel->freq > 4000 ? 0 : -1)));
-+ obdb = channel->center_freq >= 5725 ? 3 :
-+ (channel->center_freq >= 5500 ? 2 :
-+ (channel->center_freq >= 5260 ? 1 :
-+ (channel->center_freq > 4000 ? 0 : -1)));
-+
-+ if (obdb == -1)
-+ return -EINVAL;
-
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_ob[ee_mode][obdb], 3, 279, 0, true))
-@@ -1209,7 +1426,8 @@
- }
-
- /*
-- * Initialize RF5413/5414
-+ * Initialize RF5413/5414 and future chips
-+ * (until we come up with a better solution)
- */
- static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, unsigned int mode)
-@@ -1219,12 +1437,47 @@
- unsigned int rf_size, i;
- int bank = -1;
-
-- AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
-+ AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
-
- rf = ah->ah_rf_banks;
-
-+ switch (ah->ah_radio) {
-+ case AR5K_RF5413:
- rf_ini = rfregs_5413;
- rf_size = ARRAY_SIZE(rfregs_5413);
-+ break;
-+ case AR5K_RF2413:
-+ rf_ini = rfregs_2413;
-+ rf_size = ARRAY_SIZE(rfregs_2413);
-+
-+ if (mode < 2) {
-+ ATH5K_ERR(ah->ah_sc,
-+ "invalid channel mode: %i\n", mode);
-+ return -EINVAL;
-+ }
-+
-+ mode = mode - 2;
-+ break;
-+ case AR5K_RF2425:
-+ rf_ini = rfregs_2425;
-+ rf_size = ARRAY_SIZE(rfregs_2425);
-+
-+ if (mode < 2) {
-+ ATH5K_ERR(ah->ah_sc,
-+ "invalid channel mode: %i\n", mode);
-+ return -EINVAL;
-+ }
-+
-+ /* Map b to g */
-+ if (mode == 2)
-+ mode = 0;
-+ else
-+ mode = mode - 3;
-+
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-
- /* Copy values to modify them */
- for (i = 0; i < rf_size; i++) {
-@@ -1283,6 +1536,14 @@
- ah->ah_rf_banks_size = sizeof(rfregs_5413);
- func = ath5k_hw_rf5413_rfregs;
- break;
-+ case AR5K_RF2413:
-+ ah->ah_rf_banks_size = sizeof(rfregs_2413);
-+ func = ath5k_hw_rf5413_rfregs;
-+ break;
-+ case AR5K_RF2425:
-+ ah->ah_rf_banks_size = sizeof(rfregs_2425);
-+ func = ath5k_hw_rf5413_rfregs;
-+ break;
- default:
- return -EINVAL;
- }
-@@ -1321,6 +1582,16 @@
- ath5k_rfg = rfgain_5413;
- size = ARRAY_SIZE(rfgain_5413);
- break;
-+ case AR5K_RF2413:
-+ ath5k_rfg = rfgain_2413;
-+ size = ARRAY_SIZE(rfgain_2413);
-+ freq = 0; /* only 2Ghz */
-+ break;
-+ case AR5K_RF2425:
-+ ath5k_rfg = rfgain_2413;
-+ size = ARRAY_SIZE(rfgain_2413);
-+ freq = 0; /* only 2Ghz */
-+ break;
- default:
- return -EINVAL;
- }
-@@ -1395,7 +1666,6 @@
- ah->ah_gain.g_active = 1;
- break;
- case AR5K_RF5112:
-- case AR5K_RF5413: /* ??? */
- ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
- ah->ah_gain.g_step =
- &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
-@@ -1445,9 +1715,10 @@
- * newer chipsets like the AR5212A who have a completely
- * different RF/PHY part.
- */
-- athchan = (ath5k_hw_bitswap((channel->chan - 24) / 2, 5) << 1) |
-- (1 << 6) | 0x1;
--
-+ athchan = (ath5k_hw_bitswap(
-+ (ieee80211_frequency_to_channel(
-+ channel->center_freq) - 24) / 2, 5)
-+ << 1) | (1 << 6) | 0x1;
- return athchan;
- }
-
-@@ -1506,7 +1777,8 @@
- struct ieee80211_channel *channel)
- {
- struct ath5k_athchan_2ghz ath5k_channel_2ghz;
-- unsigned int ath5k_channel = channel->chan;
-+ unsigned int ath5k_channel =
-+ ieee80211_frequency_to_channel(channel->center_freq);
- u32 data0, data1, clock;
- int ret;
-
-@@ -1515,9 +1787,10 @@
- */
- data0 = data1 = 0;
-
-- if (channel->val & CHANNEL_2GHZ) {
-+ if (channel->hw_value & CHANNEL_2GHZ) {
- /* Map 2GHz channel to 5GHz Atheros channel ID */
-- ret = ath5k_hw_rf5111_chan2athchan(channel->chan,
-+ ret = ath5k_hw_rf5111_chan2athchan(
-+ ieee80211_frequency_to_channel(channel->center_freq),
- &ath5k_channel_2ghz);
- if (ret)
- return ret;
-@@ -1555,7 +1828,7 @@
- u16 c;
-
- data = data0 = data1 = data2 = 0;
-- c = channel->freq;
-+ c = channel->center_freq;
-
- /*
- * Set the channel on the RF5112 or newer
-@@ -1599,18 +1872,16 @@
- int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
- {
- int ret;
--
- /*
-- * Check bounds supported by the PHY
-- * (don't care about regulation restrictions at this point)
-- */
-- if ((channel->freq < ah->ah_capabilities.cap_range.range_2ghz_min ||
-- channel->freq > ah->ah_capabilities.cap_range.range_2ghz_max) &&
-- (channel->freq < ah->ah_capabilities.cap_range.range_5ghz_min ||
-- channel->freq > ah->ah_capabilities.cap_range.range_5ghz_max)) {
-+ * Check bounds supported by the PHY (we don't care about regultory
-+ * restrictions at this point). Note: hw_value already has the band
-+ * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok()
-+ * of the band by that */
-+ if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) {
- ATH5K_ERR(ah->ah_sc,
-- "channel out of supported range (%u MHz)\n",
-- channel->freq);
-+ "channel frequency (%u MHz) out of supported "
-+ "band range\n",
-+ channel->center_freq);
- return -EINVAL;
- }
-
-@@ -1632,9 +1903,9 @@
- if (ret)
- return ret;
-
-- ah->ah_current_channel.freq = channel->freq;
-- ah->ah_current_channel.val = channel->val;
-- ah->ah_turbo = channel->val == CHANNEL_T ? true : false;
-+ ah->ah_current_channel.center_freq = channel->center_freq;
-+ ah->ah_current_channel.hw_value = channel->hw_value;
-+ ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
-
- return 0;
- }
-@@ -1797,11 +2068,11 @@
-
- if (ret) {
- ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
-- channel->freq);
-+ channel->center_freq);
- return ret;
- }
-
-- ret = ath5k_hw_noise_floor_calibration(ah, channel->freq);
-+ ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
- if (ret)
- return ret;
-
-@@ -1825,7 +2096,7 @@
- s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
- ATH5K_TRACE(ah->ah_sc);
-
-- if (ah->ah_calibration == false ||
-+ if (!ah->ah_calibration ||
- ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
- goto done;
-
-@@ -1848,10 +2119,10 @@
- ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
-
- done:
-- ath5k_hw_noise_floor_calibration(ah, channel->freq);
-+ ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-
- /* Request RF gain */
-- if (channel->val & CHANNEL_5GHZ) {
-+ if (channel->hw_value & CHANNEL_5GHZ) {
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
- AR5K_PHY_PAPD_PROBE_TXPOWER) |
- AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
-@@ -2015,6 +2286,18 @@
- return -EINVAL;
- }
-
-+ /*
-+ * RF2413 for some reason can't
-+ * transmit anything if we call
-+ * this funtion, so we skip it
-+ * until we fix txpower.
-+ *
-+ * XXX: Assume same for RF2425
-+ * to be safe.
-+ */
-+ if ((ah->ah_radio == AR5K_RF2413) || (ah->ah_radio == AR5K_RF2425))
-+ return 0;
-+
- /* Reset TX power values */
- memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
- ah->ah_txpower.txp_tpc = tpc;
-@@ -2048,7 +2331,7 @@
- AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
- AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
-
-- if (ah->ah_txpower.txp_tpc == true)
-+ if (ah->ah_txpower.txp_tpc)
- ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
- AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
- else
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/regdom.c linux-2.6.25/drivers/net/wireless/ath5k/regdom.c
---- linux-2.6.25.old/drivers/net/wireless/ath5k/regdom.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/regdom.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,121 +0,0 @@
--/*
-- * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--
--/*
-- * Basic regulation domain extensions for the IEEE 802.11 stack
-- */
--
--#include <linux/kernel.h>
--#include <linux/string.h>
--
--#include "regdom.h"
--
--static const struct ath5k_regdommap {
-- enum ath5k_regdom dmn;
-- enum ath5k_regdom dmn5;
-- enum ath5k_regdom dmn2;
--} r_map[] = {
-- { DMN_DEFAULT, DMN_DEBUG, DMN_DEBUG },
-- { DMN_NULL_WORLD, DMN_NULL, DMN_WORLD },
-- { DMN_NULL_ETSIB, DMN_NULL, DMN_ETSIB },
-- { DMN_NULL_ETSIC, DMN_NULL, DMN_ETSIC },
-- { DMN_FCC1_FCCA, DMN_FCC1, DMN_FCCA },
-- { DMN_FCC1_WORLD, DMN_FCC1, DMN_WORLD },
-- { DMN_FCC2_FCCA, DMN_FCC2, DMN_FCCA },
-- { DMN_FCC2_WORLD, DMN_FCC2, DMN_WORLD },
-- { DMN_FCC2_ETSIC, DMN_FCC2, DMN_ETSIC },
-- { DMN_FRANCE_NULL, DMN_ETSI3, DMN_ETSI3 },
-- { DMN_FCC3_FCCA, DMN_FCC3, DMN_WORLD },
-- { DMN_ETSI1_WORLD, DMN_ETSI1, DMN_WORLD },
-- { DMN_ETSI3_ETSIA, DMN_ETSI3, DMN_WORLD },
-- { DMN_ETSI2_WORLD, DMN_ETSI2, DMN_WORLD },
-- { DMN_ETSI3_WORLD, DMN_ETSI3, DMN_WORLD },
-- { DMN_ETSI4_WORLD, DMN_ETSI4, DMN_WORLD },
-- { DMN_ETSI4_ETSIC, DMN_ETSI4, DMN_ETSIC },
-- { DMN_ETSI5_WORLD, DMN_ETSI5, DMN_WORLD },
-- { DMN_ETSI6_WORLD, DMN_ETSI6, DMN_WORLD },
-- { DMN_ETSI_NULL, DMN_ETSI1, DMN_ETSI1 },
-- { DMN_MKK1_MKKA, DMN_MKK1, DMN_MKKA },
-- { DMN_MKK1_MKKB, DMN_MKK1, DMN_MKKA },
-- { DMN_APL4_WORLD, DMN_APL4, DMN_WORLD },
-- { DMN_MKK2_MKKA, DMN_MKK2, DMN_MKKA },
-- { DMN_APL_NULL, DMN_APL1, DMN_NULL },
-- { DMN_APL2_WORLD, DMN_APL2, DMN_WORLD },
-- { DMN_APL2_APLC, DMN_APL2, DMN_WORLD },
-- { DMN_APL3_WORLD, DMN_APL3, DMN_WORLD },
-- { DMN_MKK1_FCCA, DMN_MKK1, DMN_FCCA },
-- { DMN_APL2_APLD, DMN_APL2, DMN_APLD },
-- { DMN_MKK1_MKKA1, DMN_MKK1, DMN_MKKA },
-- { DMN_MKK1_MKKA2, DMN_MKK1, DMN_MKKA },
-- { DMN_APL1_WORLD, DMN_APL1, DMN_WORLD },
-- { DMN_APL1_FCCA, DMN_APL1, DMN_FCCA },
-- { DMN_APL1_APLA, DMN_APL1, DMN_WORLD },
-- { DMN_APL1_ETSIC, DMN_APL1, DMN_ETSIC },
-- { DMN_APL2_ETSIC, DMN_APL2, DMN_ETSIC },
-- { DMN_APL5_WORLD, DMN_APL5, DMN_WORLD },
-- { DMN_WOR0_WORLD, DMN_WORLD, DMN_WORLD },
-- { DMN_WOR1_WORLD, DMN_WORLD, DMN_WORLD },
-- { DMN_WOR2_WORLD, DMN_WORLD, DMN_WORLD },
-- { DMN_WOR3_WORLD, DMN_WORLD, DMN_WORLD },
-- { DMN_WOR4_WORLD, DMN_WORLD, DMN_WORLD },
-- { DMN_WOR5_ETSIC, DMN_WORLD, DMN_WORLD },
-- { DMN_WOR01_WORLD, DMN_WORLD, DMN_WORLD },
-- { DMN_WOR02_WORLD, DMN_WORLD, DMN_WORLD },
-- { DMN_EU1_WORLD, DMN_ETSI1, DMN_WORLD },
-- { DMN_WOR9_WORLD, DMN_WORLD, DMN_WORLD },
-- { DMN_WORA_WORLD, DMN_WORLD, DMN_WORLD },
--};
--
--enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom dmn, u16 mhz)
--{
-- unsigned int i;
--
-- for (i = 0; i < ARRAY_SIZE(r_map); i++) {
-- if (r_map[i].dmn == dmn) {
-- if (mhz >= 2000 && mhz <= 3000)
-- return r_map[i].dmn2;
-- if (mhz >= IEEE80211_CHANNELS_5GHZ_MIN &&
-- mhz <= IEEE80211_CHANNELS_5GHZ_MAX)
-- return r_map[i].dmn5;
-- }
-- }
--
-- return DMN_DEBUG;
--}
--
--u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee)
--{
-- u32 regdomain = (u32)ieee;
--
-- /*
-- * Use the default regulation domain if the value is empty
-- * or not supported by the net80211 regulation code.
-- */
-- if (ath5k_regdom2flag(regdomain, IEEE80211_CHANNELS_5GHZ_MIN) ==
-- DMN_DEBUG)
-- return (u16)AR5K_TUNE_REGDOMAIN;
--
-- /* It is supported, just return the value */
-- return regdomain;
--}
--
--enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain)
--{
-- enum ath5k_regdom ieee = (enum ath5k_regdom)regdomain;
--
-- return ieee;
--}
--
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/regdom.h linux-2.6.25/drivers/net/wireless/ath5k/regdom.h
---- linux-2.6.25.old/drivers/net/wireless/ath5k/regdom.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/regdom.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,500 +0,0 @@
--/*
-- * Copyright (c) 2004, 2005 Reyk Floeter <reyk@openbsd.org>
-- *
-- * Permission to use, copy, modify, and distribute this software for any
-- * purpose with or without fee is hereby granted, provided that the above
-- * copyright notice and this permission notice appear in all copies.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-- */
--
--#ifndef _IEEE80211_REGDOMAIN_H_
--#define _IEEE80211_REGDOMAIN_H_
--
--#include <linux/types.h>
--
--/* Default regulation domain if stored value EEPROM value is invalid */
--#define AR5K_TUNE_REGDOMAIN DMN_FCC2_FCCA /* Canada */
--#define AR5K_TUNE_CTRY CTRY_DEFAULT
--
--
--enum ath5k_regdom {
-- DMN_DEFAULT = 0x00,
-- DMN_NULL_WORLD = 0x03,
-- DMN_NULL_ETSIB = 0x07,
-- DMN_NULL_ETSIC = 0x08,
-- DMN_FCC1_FCCA = 0x10,
-- DMN_FCC1_WORLD = 0x11,
-- DMN_FCC2_FCCA = 0x20,
-- DMN_FCC2_WORLD = 0x21,
-- DMN_FCC2_ETSIC = 0x22,
-- DMN_FRANCE_NULL = 0x31,
-- DMN_FCC3_FCCA = 0x3A,
-- DMN_ETSI1_WORLD = 0x37,
-- DMN_ETSI3_ETSIA = 0x32,
-- DMN_ETSI2_WORLD = 0x35,
-- DMN_ETSI3_WORLD = 0x36,
-- DMN_ETSI4_WORLD = 0x30,
-- DMN_ETSI4_ETSIC = 0x38,
-- DMN_ETSI5_WORLD = 0x39,
-- DMN_ETSI6_WORLD = 0x34,
-- DMN_ETSI_NULL = 0x33,
-- DMN_MKK1_MKKA = 0x40,
-- DMN_MKK1_MKKB = 0x41,
-- DMN_APL4_WORLD = 0x42,
-- DMN_MKK2_MKKA = 0x43,
-- DMN_APL_NULL = 0x44,
-- DMN_APL2_WORLD = 0x45,
-- DMN_APL2_APLC = 0x46,
-- DMN_APL3_WORLD = 0x47,
-- DMN_MKK1_FCCA = 0x48,
-- DMN_APL2_APLD = 0x49,
-- DMN_MKK1_MKKA1 = 0x4A,
-- DMN_MKK1_MKKA2 = 0x4B,
-- DMN_APL1_WORLD = 0x52,
-- DMN_APL1_FCCA = 0x53,
-- DMN_APL1_APLA = 0x54,
-- DMN_APL1_ETSIC = 0x55,
-- DMN_APL2_ETSIC = 0x56,
-- DMN_APL5_WORLD = 0x58,
-- DMN_WOR0_WORLD = 0x60,
-- DMN_WOR1_WORLD = 0x61,
-- DMN_WOR2_WORLD = 0x62,
-- DMN_WOR3_WORLD = 0x63,
-- DMN_WOR4_WORLD = 0x64,
-- DMN_WOR5_ETSIC = 0x65,
-- DMN_WOR01_WORLD = 0x66,
-- DMN_WOR02_WORLD = 0x67,
-- DMN_EU1_WORLD = 0x68,
-- DMN_WOR9_WORLD = 0x69,
-- DMN_WORA_WORLD = 0x6A,
--
-- DMN_APL1 = 0xf0000001,
-- DMN_APL2 = 0xf0000002,
-- DMN_APL3 = 0xf0000004,
-- DMN_APL4 = 0xf0000008,
-- DMN_APL5 = 0xf0000010,
-- DMN_ETSI1 = 0xf0000020,
-- DMN_ETSI2 = 0xf0000040,
-- DMN_ETSI3 = 0xf0000080,
-- DMN_ETSI4 = 0xf0000100,
-- DMN_ETSI5 = 0xf0000200,
-- DMN_ETSI6 = 0xf0000400,
-- DMN_ETSIA = 0xf0000800,
-- DMN_ETSIB = 0xf0001000,
-- DMN_ETSIC = 0xf0002000,
-- DMN_FCC1 = 0xf0004000,
-- DMN_FCC2 = 0xf0008000,
-- DMN_FCC3 = 0xf0010000,
-- DMN_FCCA = 0xf0020000,
-- DMN_APLD = 0xf0040000,
-- DMN_MKK1 = 0xf0080000,
-- DMN_MKK2 = 0xf0100000,
-- DMN_MKKA = 0xf0200000,
-- DMN_NULL = 0xf0400000,
-- DMN_WORLD = 0xf0800000,
-- DMN_DEBUG = 0xf1000000 /* used for debugging */
--};
--
--#define IEEE80211_DMN(_d) ((_d) & ~0xf0000000)
--
--enum ath5k_countrycode {
-- CTRY_DEFAULT = 0, /* Default domain (NA) */
-- CTRY_ALBANIA = 8, /* Albania */
-- CTRY_ALGERIA = 12, /* Algeria */
-- CTRY_ARGENTINA = 32, /* Argentina */
-- CTRY_ARMENIA = 51, /* Armenia */
-- CTRY_AUSTRALIA = 36, /* Australia */
-- CTRY_AUSTRIA = 40, /* Austria */
-- CTRY_AZERBAIJAN = 31, /* Azerbaijan */
-- CTRY_BAHRAIN = 48, /* Bahrain */
-- CTRY_BELARUS = 112, /* Belarus */
-- CTRY_BELGIUM = 56, /* Belgium */
-- CTRY_BELIZE = 84, /* Belize */
-- CTRY_BOLIVIA = 68, /* Bolivia */
-- CTRY_BRAZIL = 76, /* Brazil */
-- CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */
-- CTRY_BULGARIA = 100, /* Bulgaria */
-- CTRY_CANADA = 124, /* Canada */
-- CTRY_CHILE = 152, /* Chile */
-- CTRY_CHINA = 156, /* People's Republic of China */
-- CTRY_COLOMBIA = 170, /* Colombia */
-- CTRY_COSTA_RICA = 188, /* Costa Rica */
-- CTRY_CROATIA = 191, /* Croatia */
-- CTRY_CYPRUS = 196, /* Cyprus */
-- CTRY_CZECH = 203, /* Czech Republic */
-- CTRY_DENMARK = 208, /* Denmark */
-- CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */
-- CTRY_ECUADOR = 218, /* Ecuador */
-- CTRY_EGYPT = 818, /* Egypt */
-- CTRY_EL_SALVADOR = 222, /* El Salvador */
-- CTRY_ESTONIA = 233, /* Estonia */
-- CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */
-- CTRY_FINLAND = 246, /* Finland */
-- CTRY_FRANCE = 250, /* France */
-- CTRY_FRANCE2 = 255, /* France2 */
-- CTRY_GEORGIA = 268, /* Georgia */
-- CTRY_GERMANY = 276, /* Germany */
-- CTRY_GREECE = 300, /* Greece */
-- CTRY_GUATEMALA = 320, /* Guatemala */
-- CTRY_HONDURAS = 340, /* Honduras */
-- CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */
-- CTRY_HUNGARY = 348, /* Hungary */
-- CTRY_ICELAND = 352, /* Iceland */
-- CTRY_INDIA = 356, /* India */
-- CTRY_INDONESIA = 360, /* Indonesia */
-- CTRY_IRAN = 364, /* Iran */
-- CTRY_IRAQ = 368, /* Iraq */
-- CTRY_IRELAND = 372, /* Ireland */
-- CTRY_ISRAEL = 376, /* Israel */
-- CTRY_ITALY = 380, /* Italy */
-- CTRY_JAMAICA = 388, /* Jamaica */
-- CTRY_JAPAN = 392, /* Japan */
-- CTRY_JAPAN1 = 393, /* Japan (JP1) */
-- CTRY_JAPAN2 = 394, /* Japan (JP0) */
-- CTRY_JAPAN3 = 395, /* Japan (JP1-1) */
-- CTRY_JAPAN4 = 396, /* Japan (JE1) */
-- CTRY_JAPAN5 = 397, /* Japan (JE2) */
-- CTRY_JORDAN = 400, /* Jordan */
-- CTRY_KAZAKHSTAN = 398, /* Kazakhstan */
-- CTRY_KENYA = 404, /* Kenya */
-- CTRY_KOREA_NORTH = 408, /* North Korea */
-- CTRY_KOREA_ROC = 410, /* South Korea */
-- CTRY_KOREA_ROC2 = 411, /* South Korea */
-- CTRY_KUWAIT = 414, /* Kuwait */
-- CTRY_LATVIA = 428, /* Latvia */
-- CTRY_LEBANON = 422, /* Lebanon */
-- CTRY_LIBYA = 434, /* Libya */
-- CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */
-- CTRY_LITHUANIA = 440, /* Lithuania */
-- CTRY_LUXEMBOURG = 442, /* Luxembourg */
-- CTRY_MACAU = 446, /* Macau */
-- CTRY_MACEDONIA = 807, /* Republic of Macedonia */
-- CTRY_MALAYSIA = 458, /* Malaysia */
-- CTRY_MEXICO = 484, /* Mexico */
-- CTRY_MONACO = 492, /* Principality of Monaco */
-- CTRY_MOROCCO = 504, /* Morocco */
-- CTRY_NETHERLANDS = 528, /* Netherlands */
-- CTRY_NEW_ZEALAND = 554, /* New Zealand */
-- CTRY_NICARAGUA = 558, /* Nicaragua */
-- CTRY_NORWAY = 578, /* Norway */
-- CTRY_OMAN = 512, /* Oman */
-- CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */
-- CTRY_PANAMA = 591, /* Panama */
-- CTRY_PARAGUAY = 600, /* Paraguay */
-- CTRY_PERU = 604, /* Peru */
-- CTRY_PHILIPPINES = 608, /* Republic of the Philippines */
-- CTRY_POLAND = 616, /* Poland */
-- CTRY_PORTUGAL = 620, /* Portugal */
-- CTRY_PUERTO_RICO = 630, /* Puerto Rico */
-- CTRY_QATAR = 634, /* Qatar */
-- CTRY_ROMANIA = 642, /* Romania */
-- CTRY_RUSSIA = 643, /* Russia */
-- CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */
-- CTRY_SINGAPORE = 702, /* Singapore */
-- CTRY_SLOVAKIA = 703, /* Slovak Republic */
-- CTRY_SLOVENIA = 705, /* Slovenia */
-- CTRY_SOUTH_AFRICA = 710, /* South Africa */
-- CTRY_SPAIN = 724, /* Spain */
-- CTRY_SRI_LANKA = 728, /* Sri Lanka */
-- CTRY_SWEDEN = 752, /* Sweden */
-- CTRY_SWITZERLAND = 756, /* Switzerland */
-- CTRY_SYRIA = 760, /* Syria */
-- CTRY_TAIWAN = 158, /* Taiwan */
-- CTRY_THAILAND = 764, /* Thailand */
-- CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */
-- CTRY_TUNISIA = 788, /* Tunisia */
-- CTRY_TURKEY = 792, /* Turkey */
-- CTRY_UAE = 784, /* U.A.E. */
-- CTRY_UKRAINE = 804, /* Ukraine */
-- CTRY_UNITED_KINGDOM = 826, /* United Kingdom */
-- CTRY_UNITED_STATES = 840, /* United States */
-- CTRY_URUGUAY = 858, /* Uruguay */
-- CTRY_UZBEKISTAN = 860, /* Uzbekistan */
-- CTRY_VENEZUELA = 862, /* Venezuela */
-- CTRY_VIET_NAM = 704, /* Viet Nam */
-- CTRY_YEMEN = 887, /* Yemen */
-- CTRY_ZIMBABWE = 716, /* Zimbabwe */
--};
--
--#define IEEE80211_CHANNELS_2GHZ_MIN 2412 /* 2GHz channel 1 */
--#define IEEE80211_CHANNELS_2GHZ_MAX 2732 /* 2GHz channel 26 */
--#define IEEE80211_CHANNELS_5GHZ_MIN 5005 /* 5GHz channel 1 */
--#define IEEE80211_CHANNELS_5GHZ_MAX 6100 /* 5GHz channel 220 */
--
--struct ath5k_regchannel {
-- u16 chan;
-- enum ath5k_regdom domain;
-- u32 mode;
--};
--
--#define IEEE80211_CHANNELS_2GHZ { \
--/*2412*/ { 1, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2417*/ { 2, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2422*/ { 3, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2427*/ { 4, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2432*/ { 5, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2437*/ { 6, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2442*/ { 7, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2447*/ { 8, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2452*/ { 9, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2457*/ { 10, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2462*/ { 11, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2467*/ { 12, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2472*/ { 13, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
-- \
--/*2432*/ { 5, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2437*/ { 6, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*2442*/ { 7, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM }, \
-- \
--/*2412*/ { 1, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2417*/ { 2, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2422*/ { 3, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2427*/ { 4, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2432*/ { 5, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2437*/ { 6, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*2442*/ { 7, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2447*/ { 8, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2452*/ { 9, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2457*/ { 10, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2462*/ { 11, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2467*/ { 12, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2472*/ { 13, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
-- \
--/*2412*/ { 1, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2417*/ { 2, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2422*/ { 3, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2427*/ { 4, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2432*/ { 5, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2437*/ { 6, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*2442*/ { 7, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2447*/ { 8, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2452*/ { 9, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2457*/ { 10, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2462*/ { 11, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
-- \
--/*2412*/ { 1, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2417*/ { 2, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2422*/ { 3, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2427*/ { 4, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2432*/ { 5, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2437*/ { 6, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2442*/ { 7, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2447*/ { 8, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2452*/ { 9, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2457*/ { 10, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2462*/ { 11, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2467*/ { 12, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2472*/ { 13, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2484*/ { 14, DMN_MKKA, CHANNEL_CCK }, \
-- \
--/*2412*/ { 1, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2417*/ { 2, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2422*/ { 3, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2427*/ { 4, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2432*/ { 5, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2437*/ { 6, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*2442*/ { 7, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2447*/ { 8, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2452*/ { 9, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2457*/ { 10, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2462*/ { 11, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2467*/ { 12, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--/*2472*/ { 13, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
--}
--
--#define IEEE80211_CHANNELS_5GHZ { \
--/*5745*/ { 149, DMN_APL1, CHANNEL_OFDM }, \
--/*5765*/ { 153, DMN_APL1, CHANNEL_OFDM }, \
--/*5785*/ { 157, DMN_APL1, CHANNEL_OFDM }, \
--/*5805*/ { 161, DMN_APL1, CHANNEL_OFDM }, \
--/*5825*/ { 165, DMN_APL1, CHANNEL_OFDM }, \
-- \
--/*5745*/ { 149, DMN_APL2, CHANNEL_OFDM }, \
--/*5765*/ { 153, DMN_APL2, CHANNEL_OFDM }, \
--/*5785*/ { 157, DMN_APL2, CHANNEL_OFDM }, \
--/*5805*/ { 161, DMN_APL2, CHANNEL_OFDM }, \
-- \
--/*5280*/ { 56, DMN_APL3, CHANNEL_OFDM }, \
--/*5300*/ { 60, DMN_APL3, CHANNEL_OFDM }, \
--/*5320*/ { 64, DMN_APL3, CHANNEL_OFDM }, \
--/*5745*/ { 149, DMN_APL3, CHANNEL_OFDM }, \
--/*5765*/ { 153, DMN_APL3, CHANNEL_OFDM }, \
--/*5785*/ { 157, DMN_APL3, CHANNEL_OFDM }, \
--/*5805*/ { 161, DMN_APL3, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_APL4, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_APL4, CHANNEL_OFDM }, \
--/*5220*/ { 44, DMN_APL4, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_APL4, CHANNEL_OFDM }, \
--/*5745*/ { 149, DMN_APL4, CHANNEL_OFDM }, \
--/*5765*/ { 153, DMN_APL4, CHANNEL_OFDM }, \
--/*5785*/ { 157, DMN_APL4, CHANNEL_OFDM }, \
--/*5805*/ { 161, DMN_APL4, CHANNEL_OFDM }, \
--/*5825*/ { 165, DMN_APL4, CHANNEL_OFDM }, \
-- \
--/*5745*/ { 149, DMN_APL5, CHANNEL_OFDM }, \
--/*5765*/ { 153, DMN_APL5, CHANNEL_OFDM }, \
--/*5785*/ { 157, DMN_APL5, CHANNEL_OFDM }, \
--/*5805*/ { 161, DMN_APL5, CHANNEL_OFDM }, \
--/*5825*/ { 165, DMN_APL5, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5220*/ { 44, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5260*/ { 52, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5280*/ { 56, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5300*/ { 60, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5320*/ { 64, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5500*/ { 100, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5520*/ { 104, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5540*/ { 108, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5560*/ { 112, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5580*/ { 116, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5600*/ { 120, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5620*/ { 124, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5640*/ { 128, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5660*/ { 132, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5680*/ { 136, DMN_ETSI1, CHANNEL_OFDM }, \
--/*5700*/ { 140, DMN_ETSI1, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_ETSI2, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_ETSI2, CHANNEL_OFDM }, \
--/*5220*/ { 44, DMN_ETSI2, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_ETSI2, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_ETSI3, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_ETSI3, CHANNEL_OFDM }, \
--/*5220*/ { 44, DMN_ETSI3, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_ETSI3, CHANNEL_OFDM }, \
--/*5260*/ { 52, DMN_ETSI3, CHANNEL_OFDM }, \
--/*5280*/ { 56, DMN_ETSI3, CHANNEL_OFDM }, \
--/*5300*/ { 60, DMN_ETSI3, CHANNEL_OFDM }, \
--/*5320*/ { 64, DMN_ETSI3, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_ETSI4, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_ETSI4, CHANNEL_OFDM }, \
--/*5220*/ { 44, DMN_ETSI4, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_ETSI4, CHANNEL_OFDM }, \
--/*5260*/ { 52, DMN_ETSI4, CHANNEL_OFDM }, \
--/*5280*/ { 56, DMN_ETSI4, CHANNEL_OFDM }, \
--/*5300*/ { 60, DMN_ETSI4, CHANNEL_OFDM }, \
--/*5320*/ { 64, DMN_ETSI4, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_ETSI5, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_ETSI5, CHANNEL_OFDM }, \
--/*5220*/ { 44, DMN_ETSI5, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_ETSI5, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5220*/ { 44, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5260*/ { 52, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5280*/ { 56, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5500*/ { 100, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5520*/ { 104, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5540*/ { 108, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5560*/ { 112, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5580*/ { 116, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5600*/ { 120, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5620*/ { 124, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5640*/ { 128, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5660*/ { 132, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5680*/ { 136, DMN_ETSI6, CHANNEL_OFDM }, \
--/*5700*/ { 140, DMN_ETSI6, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_FCC1, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_FCC1, CHANNEL_OFDM }, \
--/*5210*/ { 42, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5220*/ { 44, DMN_FCC1, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_FCC1, CHANNEL_OFDM }, \
--/*5250*/ { 50, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5260*/ { 52, DMN_FCC1, CHANNEL_OFDM }, \
--/*5280*/ { 56, DMN_FCC1, CHANNEL_OFDM }, \
--/*5290*/ { 58, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5300*/ { 60, DMN_FCC1, CHANNEL_OFDM }, \
--/*5320*/ { 64, DMN_FCC1, CHANNEL_OFDM }, \
--/*5745*/ { 149, DMN_FCC1, CHANNEL_OFDM }, \
--/*5760*/ { 152, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5765*/ { 153, DMN_FCC1, CHANNEL_OFDM }, \
--/*5785*/ { 157, DMN_FCC1, CHANNEL_OFDM }, \
--/*5800*/ { 160, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5805*/ { 161, DMN_FCC1, CHANNEL_OFDM }, \
--/*5825*/ { 165, DMN_FCC1, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_FCC2, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_FCC2, CHANNEL_OFDM }, \
--/*5220*/ { 44, DMN_FCC2, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_FCC2, CHANNEL_OFDM }, \
--/*5260*/ { 52, DMN_FCC2, CHANNEL_OFDM }, \
--/*5280*/ { 56, DMN_FCC2, CHANNEL_OFDM }, \
--/*5300*/ { 60, DMN_FCC2, CHANNEL_OFDM }, \
--/*5320*/ { 64, DMN_FCC2, CHANNEL_OFDM }, \
--/*5745*/ { 149, DMN_FCC2, CHANNEL_OFDM }, \
--/*5765*/ { 153, DMN_FCC2, CHANNEL_OFDM }, \
--/*5785*/ { 157, DMN_FCC2, CHANNEL_OFDM }, \
--/*5805*/ { 161, DMN_FCC2, CHANNEL_OFDM }, \
--/*5825*/ { 165, DMN_FCC2, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_FCC3, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_FCC3, CHANNEL_OFDM }, \
--/*5210*/ { 42, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5220*/ { 44, DMN_FCC3, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_FCC3, CHANNEL_OFDM }, \
--/*5250*/ { 50, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5260*/ { 52, DMN_FCC3, CHANNEL_OFDM }, \
--/*5280*/ { 56, DMN_FCC3, CHANNEL_OFDM }, \
--/*5290*/ { 58, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5300*/ { 60, DMN_FCC3, CHANNEL_OFDM }, \
--/*5320*/ { 64, DMN_FCC3, CHANNEL_OFDM }, \
--/*5500*/ { 100, DMN_FCC3, CHANNEL_OFDM }, \
--/*5520*/ { 104, DMN_FCC3, CHANNEL_OFDM }, \
--/*5540*/ { 108, DMN_FCC3, CHANNEL_OFDM }, \
--/*5560*/ { 112, DMN_FCC3, CHANNEL_OFDM }, \
--/*5580*/ { 116, DMN_FCC3, CHANNEL_OFDM }, \
--/*5600*/ { 120, DMN_FCC3, CHANNEL_OFDM }, \
--/*5620*/ { 124, DMN_FCC3, CHANNEL_OFDM }, \
--/*5640*/ { 128, DMN_FCC3, CHANNEL_OFDM }, \
--/*5660*/ { 132, DMN_FCC3, CHANNEL_OFDM }, \
--/*5680*/ { 136, DMN_FCC3, CHANNEL_OFDM }, \
--/*5700*/ { 140, DMN_FCC3, CHANNEL_OFDM }, \
--/*5745*/ { 149, DMN_FCC3, CHANNEL_OFDM }, \
--/*5760*/ { 152, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5765*/ { 153, DMN_FCC3, CHANNEL_OFDM }, \
--/*5785*/ { 157, DMN_FCC3, CHANNEL_OFDM }, \
--/*5800*/ { 160, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
--/*5805*/ { 161, DMN_FCC3, CHANNEL_OFDM }, \
--/*5825*/ { 165, DMN_FCC3, CHANNEL_OFDM }, \
-- \
--/*5170*/ { 34, DMN_MKK1, CHANNEL_OFDM }, \
--/*5190*/ { 38, DMN_MKK1, CHANNEL_OFDM }, \
--/*5210*/ { 42, DMN_MKK1, CHANNEL_OFDM }, \
--/*5230*/ { 46, DMN_MKK1, CHANNEL_OFDM }, \
-- \
--/*5040*/ { 8, DMN_MKK2, CHANNEL_OFDM }, \
--/*5060*/ { 12, DMN_MKK2, CHANNEL_OFDM }, \
--/*5080*/ { 16, DMN_MKK2, CHANNEL_OFDM }, \
--/*5170*/ { 34, DMN_MKK2, CHANNEL_OFDM }, \
--/*5190*/ { 38, DMN_MKK2, CHANNEL_OFDM }, \
--/*5210*/ { 42, DMN_MKK2, CHANNEL_OFDM }, \
--/*5230*/ { 46, DMN_MKK2, CHANNEL_OFDM }, \
-- \
--/*5180*/ { 36, DMN_WORLD, CHANNEL_OFDM }, \
--/*5200*/ { 40, DMN_WORLD, CHANNEL_OFDM }, \
--/*5220*/ { 44, DMN_WORLD, CHANNEL_OFDM }, \
--/*5240*/ { 48, DMN_WORLD, CHANNEL_OFDM }, \
--}
--
--enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom, u16);
--u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee);
--enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain);
--
--#endif
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/ath5k/reg.h linux-2.6.25/drivers/net/wireless/ath5k/reg.h
---- linux-2.6.25.old/drivers/net/wireless/ath5k/reg.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/ath5k/reg.h 2008-04-19 13:54:59.000000000 +0200
-@@ -1923,7 +1923,9 @@
- #define AR5K_PHY_SDELAY_32MHZ 0x000000ff
- #define AR5K_PHY_SPENDING 0x99f8
- #define AR5K_PHY_SPENDING_RF5111 0x00000018
--#define AR5K_PHY_SPENDING_RF5112 0x00000014
-+#define AR5K_PHY_SPENDING_RF5112 0x00000014 /* <- i 've only seen this on 2425 dumps ! */
-+#define AR5K_PHY_SPENDING_RF5112A 0x0000000e /* but since i only have 5112A-based chips */
-+#define AR5K_PHY_SPENDING_RF5424 0x00000012 /* to test it might be also for old 5112. */
-
- /*
- * Misc PHY/radio registers [5110 - 5111]
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/atmel.c linux-2.6.25/drivers/net/wireless/atmel.c
---- linux-2.6.25.old/drivers/net/wireless/atmel.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/atmel.c 2008-04-19 13:54:59.000000000 +0200
-@@ -66,6 +66,7 @@
- #include <linux/device.h>
- #include <linux/moduleparam.h>
- #include <linux/firmware.h>
-+#include <linux/jiffies.h>
- #include <net/ieee80211.h>
- #include "atmel.h"
-
-@@ -516,7 +517,7 @@
- SITE_SURVEY_IN_PROGRESS,
- SITE_SURVEY_COMPLETED
- } site_survey_state;
-- time_t last_survey;
-+ unsigned long last_survey;
-
- int station_was_associated, station_is_associated;
- int fast_scan;
-@@ -2283,7 +2284,7 @@
- return -EAGAIN;
-
- /* Timeout old surveys. */
-- if ((jiffies - priv->last_survey) > (20 * HZ))
-+ if (time_after(jiffies, priv->last_survey + 20 * HZ))
- priv->site_survey_state = SITE_SURVEY_IDLE;
- priv->last_survey = jiffies;
-
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/b43.h linux-2.6.25/drivers/net/wireless/b43/b43.h
---- linux-2.6.25.old/drivers/net/wireless/b43/b43.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/b43.h 2008-04-19 13:54:59.000000000 +0200
-@@ -75,6 +75,23 @@
- #define B43_MMIO_DMA64_BASE4 0x300
- #define B43_MMIO_DMA64_BASE5 0x340
-
-+/* PIO on core rev < 11 */
-+#define B43_MMIO_PIO_BASE0 0x300
-+#define B43_MMIO_PIO_BASE1 0x310
-+#define B43_MMIO_PIO_BASE2 0x320
-+#define B43_MMIO_PIO_BASE3 0x330
-+#define B43_MMIO_PIO_BASE4 0x340
-+#define B43_MMIO_PIO_BASE5 0x350
-+#define B43_MMIO_PIO_BASE6 0x360
-+#define B43_MMIO_PIO_BASE7 0x370
-+/* PIO on core rev >= 11 */
-+#define B43_MMIO_PIO11_BASE0 0x200
-+#define B43_MMIO_PIO11_BASE1 0x240
-+#define B43_MMIO_PIO11_BASE2 0x280
-+#define B43_MMIO_PIO11_BASE3 0x2C0
-+#define B43_MMIO_PIO11_BASE4 0x300
-+#define B43_MMIO_PIO11_BASE5 0x340
-+
- #define B43_MMIO_PHY_VER 0x3E0
- #define B43_MMIO_PHY_RADIO 0x3E2
- #define B43_MMIO_PHY0 0x3E6
-@@ -94,11 +111,14 @@
- #define B43_MMIO_GPIO_MASK 0x49E
- #define B43_MMIO_TSF_CFP_START_LOW 0x604
- #define B43_MMIO_TSF_CFP_START_HIGH 0x606
-+#define B43_MMIO_TSF_CFP_PRETBTT 0x612
- #define B43_MMIO_TSF_0 0x632 /* core rev < 3 only */
- #define B43_MMIO_TSF_1 0x634 /* core rev < 3 only */
- #define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */
- #define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */
- #define B43_MMIO_RNG 0x65A
-+#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
-+#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
- #define B43_MMIO_POWERUP_DELAY 0x6A8
-
- /* SPROM boardflags_lo values */
-@@ -144,7 +164,8 @@
- #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */
- #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */
- #define B43_SHM_SH_HOSTFLO 0x005E /* Hostflags for ucode options (low) */
--#define B43_SHM_SH_HOSTFHI 0x0060 /* Hostflags for ucode options (high) */
-+#define B43_SHM_SH_HOSTFMI 0x0060 /* Hostflags for ucode options (middle) */
-+#define B43_SHM_SH_HOSTFHI 0x0062 /* Hostflags for ucode options (high) */
- #define B43_SHM_SH_RFATT 0x0064 /* Current radio attenuation value */
- #define B43_SHM_SH_RADAR 0x0066 /* Radar register */
- #define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */
-@@ -232,31 +253,41 @@
- #define B43_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4)
-
- /* HostFlags. See b43_hf_read/write() */
--#define B43_HF_ANTDIVHELP 0x00000001 /* ucode antenna div helper */
--#define B43_HF_SYMW 0x00000002 /* G-PHY SYM workaround */
--#define B43_HF_RXPULLW 0x00000004 /* RX pullup workaround */
--#define B43_HF_CCKBOOST 0x00000008 /* 4dB CCK power boost (exclusive with OFDM boost) */
--#define B43_HF_BTCOEX 0x00000010 /* Bluetooth coexistance */
--#define B43_HF_GDCW 0x00000020 /* G-PHY DV canceller filter bw workaround */
--#define B43_HF_OFDMPABOOST 0x00000040 /* Enable PA gain boost for OFDM */
--#define B43_HF_ACPR 0x00000080 /* Disable for Japan, channel 14 */
--#define B43_HF_EDCF 0x00000100 /* on if WME and MAC suspended */
--#define B43_HF_TSSIRPSMW 0x00000200 /* TSSI reset PSM ucode workaround */
--#define B43_HF_DSCRQ 0x00000400 /* Disable slow clock request in ucode */
--#define B43_HF_ACIW 0x00000800 /* ACI workaround: shift bits by 2 on PHY CRS */
--#define B43_HF_2060W 0x00001000 /* 2060 radio workaround */
--#define B43_HF_RADARW 0x00002000 /* Radar workaround */
--#define B43_HF_USEDEFKEYS 0x00004000 /* Enable use of default keys */
--#define B43_HF_BT4PRIOCOEX 0x00010000 /* Bluetooth 2-priority coexistance */
--#define B43_HF_FWKUP 0x00020000 /* Fast wake-up ucode */
--#define B43_HF_VCORECALC 0x00040000 /* Force VCO recalculation when powering up synthpu */
--#define B43_HF_PCISCW 0x00080000 /* PCI slow clock workaround */
--#define B43_HF_4318TSSI 0x00200000 /* 4318 TSSI */
--#define B43_HF_FBCMCFIFO 0x00400000 /* Flush bcast/mcast FIFO immediately */
--#define B43_HF_HWPCTL 0x00800000 /* Enable hardwarre power control */
--#define B43_HF_BTCOEXALT 0x01000000 /* Bluetooth coexistance in alternate pins */
--#define B43_HF_TXBTCHECK 0x02000000 /* Bluetooth check during transmission */
--#define B43_HF_SKCFPUP 0x04000000 /* Skip CFP update */
-+#define B43_HF_ANTDIVHELP 0x000000000001ULL /* ucode antenna div helper */
-+#define B43_HF_SYMW 0x000000000002ULL /* G-PHY SYM workaround */
-+#define B43_HF_RXPULLW 0x000000000004ULL /* RX pullup workaround */
-+#define B43_HF_CCKBOOST 0x000000000008ULL /* 4dB CCK power boost (exclusive with OFDM boost) */
-+#define B43_HF_BTCOEX 0x000000000010ULL /* Bluetooth coexistance */
-+#define B43_HF_GDCW 0x000000000020ULL /* G-PHY DC canceller filter bw workaround */
-+#define B43_HF_OFDMPABOOST 0x000000000040ULL /* Enable PA gain boost for OFDM */
-+#define B43_HF_ACPR 0x000000000080ULL /* Disable for Japan, channel 14 */
-+#define B43_HF_EDCF 0x000000000100ULL /* on if WME and MAC suspended */
-+#define B43_HF_TSSIRPSMW 0x000000000200ULL /* TSSI reset PSM ucode workaround */
-+#define B43_HF_20IN40IQW 0x000000000200ULL /* 20 in 40 MHz I/Q workaround (rev >= 13 only) */
-+#define B43_HF_DSCRQ 0x000000000400ULL /* Disable slow clock request in ucode */
-+#define B43_HF_ACIW 0x000000000800ULL /* ACI workaround: shift bits by 2 on PHY CRS */
-+#define B43_HF_2060W 0x000000001000ULL /* 2060 radio workaround */
-+#define B43_HF_RADARW 0x000000002000ULL /* Radar workaround */
-+#define B43_HF_USEDEFKEYS 0x000000004000ULL /* Enable use of default keys */
-+#define B43_HF_AFTERBURNER 0x000000008000ULL /* Afterburner enabled */
-+#define B43_HF_BT4PRIOCOEX 0x000000010000ULL /* Bluetooth 4-priority coexistance */
-+#define B43_HF_FWKUP 0x000000020000ULL /* Fast wake-up ucode */
-+#define B43_HF_VCORECALC 0x000000040000ULL /* Force VCO recalculation when powering up synthpu */
-+#define B43_HF_PCISCW 0x000000080000ULL /* PCI slow clock workaround */
-+#define B43_HF_4318TSSI 0x000000200000ULL /* 4318 TSSI */
-+#define B43_HF_FBCMCFIFO 0x000000400000ULL /* Flush bcast/mcast FIFO immediately */
-+#define B43_HF_HWPCTL 0x000000800000ULL /* Enable hardwarre power control */
-+#define B43_HF_BTCOEXALT 0x000001000000ULL /* Bluetooth coexistance in alternate pins */
-+#define B43_HF_TXBTCHECK 0x000002000000ULL /* Bluetooth check during transmission */
-+#define B43_HF_SKCFPUP 0x000004000000ULL /* Skip CFP update */
-+#define B43_HF_N40W 0x000008000000ULL /* N PHY 40 MHz workaround (rev >= 13 only) */
-+#define B43_HF_ANTSEL 0x000020000000ULL /* Antenna selection (for testing antenna div.) */
-+#define B43_HF_BT3COEXT 0x000020000000ULL /* Bluetooth 3-wire coexistence (rev >= 13 only) */
-+#define B43_HF_BTCANT 0x000040000000ULL /* Bluetooth coexistence (antenna mode) (rev >= 13 only) */
-+#define B43_HF_ANTSELEN 0x000100000000ULL /* Antenna selection enabled (rev >= 13 only) */
-+#define B43_HF_ANTSELMODE 0x000200000000ULL /* Antenna selection mode (rev >= 13 only) */
-+#define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */
-+#define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */
-
- /* MacFilter offsets. */
- #define B43_MACFILTER_SELF 0x0000
-@@ -380,7 +411,6 @@
-
- #define B43_IRQ_ALL 0xFFFFFFFF
- #define B43_IRQ_MASKTEMPLATE (B43_IRQ_MAC_SUSPENDED | \
-- B43_IRQ_BEACON | \
- B43_IRQ_TBTT_INDI | \
- B43_IRQ_ATIM_END | \
- B43_IRQ_PMQ | \
-@@ -429,7 +459,6 @@
- };
-
- struct b43_dmaring;
--struct b43_pioqueue;
-
- /* The firmware file header */
- #define B43_FW_TYPE_UCODE 'u'
-@@ -458,20 +487,13 @@
- } __attribute__((__packed__));
-
-
--#define B43_PHYMODE(phytype) (1 << (phytype))
--#define B43_PHYMODE_A B43_PHYMODE(B43_PHYTYPE_A)
--#define B43_PHYMODE_B B43_PHYMODE(B43_PHYTYPE_B)
--#define B43_PHYMODE_G B43_PHYMODE(B43_PHYTYPE_G)
--
- struct b43_phy {
-- /* Possible PHYMODEs on this PHY */
-- u8 possible_phymodes;
-+ /* Band support flags. */
-+ bool supports_2ghz;
-+ bool supports_5ghz;
-+
- /* GMODE bit enabled? */
- bool gmode;
-- /* Possible ieee80211 subsystem hwmodes for this PHY.
-- * Which mode is selected, depends on thr GMODE enabled bit */
--#define B43_MAX_PHYHWMODES 2
-- struct ieee80211_hw_mode hwmodes[B43_MAX_PHYHWMODES];
-
- /* Analog Type */
- u8 analog;
-@@ -583,15 +605,27 @@
-
- /* Data structures for DMA transmission, per 80211 core. */
- struct b43_dma {
-- struct b43_dmaring *tx_ring0;
-- struct b43_dmaring *tx_ring1;
-- struct b43_dmaring *tx_ring2;
-- struct b43_dmaring *tx_ring3;
-- struct b43_dmaring *tx_ring4;
-- struct b43_dmaring *tx_ring5;
-+ struct b43_dmaring *tx_ring_AC_BK; /* Background */
-+ struct b43_dmaring *tx_ring_AC_BE; /* Best Effort */
-+ struct b43_dmaring *tx_ring_AC_VI; /* Video */
-+ struct b43_dmaring *tx_ring_AC_VO; /* Voice */
-+ struct b43_dmaring *tx_ring_mcast; /* Multicast */
-+
-+ struct b43_dmaring *rx_ring;
-+};
-+
-+struct b43_pio_txqueue;
-+struct b43_pio_rxqueue;
-+
-+/* Data structures for PIO transmission, per 80211 core. */
-+struct b43_pio {
-+ struct b43_pio_txqueue *tx_queue_AC_BK; /* Background */
-+ struct b43_pio_txqueue *tx_queue_AC_BE; /* Best Effort */
-+ struct b43_pio_txqueue *tx_queue_AC_VI; /* Video */
-+ struct b43_pio_txqueue *tx_queue_AC_VO; /* Voice */
-+ struct b43_pio_txqueue *tx_queue_mcast; /* Multicast */
-
-- struct b43_dmaring *rx_ring0;
-- struct b43_dmaring *rx_ring3; /* only available on core.rev < 5 */
-+ struct b43_pio_rxqueue *rx_queue;
- };
-
- /* Context information for a noise calculation (Link Quality). */
-@@ -617,6 +651,35 @@
- u8 algorithm;
- };
-
-+/* SHM offsets to the QOS data structures for the 4 different queues. */
-+#define B43_QOS_PARAMS(queue) (B43_SHM_SH_EDCFQ + \
-+ (B43_NR_QOSPARAMS * sizeof(u16) * (queue)))
-+#define B43_QOS_BACKGROUND B43_QOS_PARAMS(0)
-+#define B43_QOS_BESTEFFORT B43_QOS_PARAMS(1)
-+#define B43_QOS_VIDEO B43_QOS_PARAMS(2)
-+#define B43_QOS_VOICE B43_QOS_PARAMS(3)
-+
-+/* QOS parameter hardware data structure offsets. */
-+#define B43_NR_QOSPARAMS 22
-+enum {
-+ B43_QOSPARAM_TXOP = 0,
-+ B43_QOSPARAM_CWMIN,
-+ B43_QOSPARAM_CWMAX,
-+ B43_QOSPARAM_CWCUR,
-+ B43_QOSPARAM_AIFS,
-+ B43_QOSPARAM_BSLOTS,
-+ B43_QOSPARAM_REGGAP,
-+ B43_QOSPARAM_STATUS,
-+};
-+
-+/* QOS parameters for a queue. */
-+struct b43_qos_params {
-+ /* The QOS parameters */
-+ struct ieee80211_tx_queue_params p;
-+ /* Does this need to get uploaded to hardware? */
-+ bool need_hw_update;
-+};
-+
- struct b43_wldev;
-
- /* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
-@@ -667,8 +730,16 @@
- /* The beacon we are currently using (AP or IBSS mode).
- * This beacon stuff is protected by the irq_lock. */
- struct sk_buff *current_beacon;
-+ struct ieee80211_tx_control beacon_txctl;
- bool beacon0_uploaded;
- bool beacon1_uploaded;
-+ struct work_struct beacon_update_trigger;
-+
-+ /* The current QOS parameters for the 4 queues.
-+ * This is protected by the irq_lock. */
-+ struct b43_qos_params qos_params[4];
-+ /* Workqueue for updating QOS parameters in hardware. */
-+ struct work_struct qos_update_work;
- };
-
- /* In-memory representation of a cached microcode file. */
-@@ -727,7 +798,6 @@
-
- bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */
- bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */
-- bool short_preamble; /* TRUE, if short preamble is enabled. */
- bool short_slot; /* TRUE, if short slot timing is enabled. */
- bool radio_hw_enable; /* saved state of radio hardware enabled state */
- bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */
-@@ -735,8 +805,15 @@
- /* PHY/Radio device. */
- struct b43_phy phy;
-
-+ union {
- /* DMA engines. */
- struct b43_dma dma;
-+ /* PIO engines. */
-+ struct b43_pio pio;
-+ };
-+ /* Use b43_using_pio_transfers() to check whether we are using
-+ * DMA or PIO data transfers. */
-+ bool __using_pio_transfers;
-
- /* Various statistics about the physical device. */
- struct b43_stats stats;
-@@ -820,6 +897,22 @@
- ssb_write32(dev->dev, offset, value);
- }
-
-+static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
-+{
-+#ifdef CONFIG_B43_PIO
-+ return dev->__using_pio_transfers;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+#ifdef CONFIG_B43_FORCE_PIO
-+# define B43_FORCE_PIO 1
-+#else
-+# define B43_FORCE_PIO 0
-+#endif
-+
-+
- /* Message printing */
- void b43info(struct b43_wl *wl, const char *fmt, ...)
- __attribute__ ((format(printf, 2, 3)));
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/dma.c linux-2.6.25/drivers/net/wireless/b43/dma.c
---- linux-2.6.25.old/drivers/net/wireless/b43/dma.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/dma.c 2008-04-19 16:24:28.000000000 +0200
-@@ -38,6 +38,7 @@
- #include <linux/delay.h>
- #include <linux/skbuff.h>
- #include <linux/etherdevice.h>
-+#include <asm/div64.h>
-
-
- /* 32bit DMA ops. */
-@@ -291,52 +292,6 @@
- return slot;
- }
-
--/* Mac80211-queue to b43-ring mapping */
--static struct b43_dmaring *priority_to_txring(struct b43_wldev *dev,
-- int queue_priority)
--{
-- struct b43_dmaring *ring;
--
--/*FIXME: For now we always run on TX-ring-1 */
-- return dev->dma.tx_ring1;
--
-- /* 0 = highest priority */
-- switch (queue_priority) {
-- default:
-- B43_WARN_ON(1);
-- /* fallthrough */
-- case 0:
-- ring = dev->dma.tx_ring3;
-- break;
-- case 1:
-- ring = dev->dma.tx_ring2;
-- break;
-- case 2:
-- ring = dev->dma.tx_ring1;
-- break;
-- case 3:
-- ring = dev->dma.tx_ring0;
-- break;
-- }
--
-- return ring;
--}
--
--/* b43-ring to mac80211-queue mapping */
--static inline int txring_to_priority(struct b43_dmaring *ring)
--{
-- static const u8 idx_to_prio[] = { 3, 2, 1, 0, };
-- unsigned int index;
--
--/*FIXME: have only one queue, for now */
-- return 0;
--
-- index = ring->index;
-- if (B43_WARN_ON(index >= ARRAY_SIZE(idx_to_prio)))
-- index = 0;
-- return idx_to_prio[index];
--}
--
- static u16 b43_dmacontroller_base(enum b43_dmatype type, int controller_idx)
- {
- static const u16 map64[] = {
-@@ -596,7 +551,6 @@
- struct b43_dmadesc_meta *meta, gfp_t gfp_flags)
- {
- struct b43_rxhdr_fw4 *rxhdr;
-- struct b43_hwtxstatus *txstat;
- dma_addr_t dmaaddr;
- struct sk_buff *skb;
-
-@@ -632,8 +586,6 @@
-
- rxhdr = (struct b43_rxhdr_fw4 *)(skb->data);
- rxhdr->frame_len = 0;
-- txstat = (struct b43_hwtxstatus *)(skb->data);
-- txstat->cookie = 0;
-
- return 0;
- }
-@@ -822,6 +774,18 @@
- return DMA_30BIT_MASK;
- }
-
-+static enum b43_dmatype dma_mask_to_engine_type(u64 dmamask)
-+{
-+ if (dmamask == DMA_30BIT_MASK)
-+ return B43_DMA_30BIT;
-+ if (dmamask == DMA_32BIT_MASK)
-+ return B43_DMA_32BIT;
-+ if (dmamask == DMA_64BIT_MASK)
-+ return B43_DMA_64BIT;
-+ B43_WARN_ON(1);
-+ return B43_DMA_30BIT;
-+}
-+
- /* Main initialization function. */
- static
- struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
-@@ -937,16 +901,52 @@
- goto out;
- }
-
-+#define divide(a, b) ({ \
-+ typeof(a) __a = a; \
-+ do_div(__a, b); \
-+ __a; \
-+ })
-+
-+#define modulo(a, b) ({ \
-+ typeof(a) __a = a; \
-+ do_div(__a, b); \
-+ })
-+
- /* Main cleanup function. */
--static void b43_destroy_dmaring(struct b43_dmaring *ring)
-+static void b43_destroy_dmaring(struct b43_dmaring *ring,
-+ const char *ringname)
- {
- if (!ring)
- return;
-
-- b43dbg(ring->dev->wl, "DMA-%u 0x%04X (%s) max used slots: %d/%d\n",
-- (unsigned int)(ring->type),
-- ring->mmio_base,
-- (ring->tx) ? "TX" : "RX", ring->max_used_slots, ring->nr_slots);
-+#ifdef CONFIG_B43_DEBUG
-+ {
-+ /* Print some statistics. */
-+ u64 failed_packets = ring->nr_failed_tx_packets;
-+ u64 succeed_packets = ring->nr_succeed_tx_packets;
-+ u64 nr_packets = failed_packets + succeed_packets;
-+ u64 permille_failed = 0, average_tries = 0;
-+
-+ if (nr_packets)
-+ permille_failed = divide(failed_packets * 1000, nr_packets);
-+ if (nr_packets)
-+ average_tries = divide(ring->nr_total_packet_tries * 100, nr_packets);
-+
-+ b43dbg(ring->dev->wl, "DMA-%u %s: "
-+ "Used slots %d/%d, Failed frames %llu/%llu = %llu.%01llu%%, "
-+ "Average tries %llu.%02llu\n",
-+ (unsigned int)(ring->type), ringname,
-+ ring->max_used_slots,
-+ ring->nr_slots,
-+ (unsigned long long)failed_packets,
-+ (unsigned long long)nr_packets,
-+ (unsigned long long)divide(permille_failed, 10),
-+ (unsigned long long)modulo(permille_failed, 10),
-+ (unsigned long long)divide(average_tries, 100),
-+ (unsigned long long)modulo(average_tries, 100));
-+ }
-+#endif /* DEBUG */
-+
- /* Device IRQs are disabled prior entering this function,
- * so no need to take care of concurrency with rx handler stuff.
- */
-@@ -959,51 +959,36 @@
- kfree(ring);
- }
-
-+#define destroy_ring(dma, ring) do { \
-+ b43_destroy_dmaring((dma)->ring, __stringify(ring)); \
-+ (dma)->ring = NULL; \
-+ } while (0)
-+
- void b43_dma_free(struct b43_wldev *dev)
- {
-- struct b43_dma *dma = &dev->dma;
-+ struct b43_dma *dma;
-
-- b43_destroy_dmaring(dma->rx_ring3);
-- dma->rx_ring3 = NULL;
-- b43_destroy_dmaring(dma->rx_ring0);
-- dma->rx_ring0 = NULL;
--
-- b43_destroy_dmaring(dma->tx_ring5);
-- dma->tx_ring5 = NULL;
-- b43_destroy_dmaring(dma->tx_ring4);
-- dma->tx_ring4 = NULL;
-- b43_destroy_dmaring(dma->tx_ring3);
-- dma->tx_ring3 = NULL;
-- b43_destroy_dmaring(dma->tx_ring2);
-- dma->tx_ring2 = NULL;
-- b43_destroy_dmaring(dma->tx_ring1);
-- dma->tx_ring1 = NULL;
-- b43_destroy_dmaring(dma->tx_ring0);
-- dma->tx_ring0 = NULL;
-+ if (b43_using_pio_transfers(dev))
-+ return;
-+ dma = &dev->dma;
-+
-+ destroy_ring(dma, rx_ring);
-+ destroy_ring(dma, tx_ring_AC_BK);
-+ destroy_ring(dma, tx_ring_AC_BE);
-+ destroy_ring(dma, tx_ring_AC_VI);
-+ destroy_ring(dma, tx_ring_AC_VO);
-+ destroy_ring(dma, tx_ring_mcast);
- }
-
- int b43_dma_init(struct b43_wldev *dev)
- {
- struct b43_dma *dma = &dev->dma;
-- struct b43_dmaring *ring;
- int err;
- u64 dmamask;
- enum b43_dmatype type;
-
- dmamask = supported_dma_mask(dev);
-- switch (dmamask) {
-- default:
-- B43_WARN_ON(1);
-- case DMA_30BIT_MASK:
-- type = B43_DMA_30BIT;
-- break;
-- case DMA_32BIT_MASK:
-- type = B43_DMA_32BIT;
-- break;
-- case DMA_64BIT_MASK:
-- type = B43_DMA_64BIT;
-- break;
-- }
-+ type = dma_mask_to_engine_type(dmamask);
- err = ssb_dma_set_mask(dev->dev, dmamask);
- if (err) {
- b43err(dev->wl, "The machine/kernel does not support "
-@@ -1015,83 +1000,57 @@
-
- err = -ENOMEM;
- /* setup TX DMA channels. */
-- ring = b43_setup_dmaring(dev, 0, 1, type);
-- if (!ring)
-+ dma->tx_ring_AC_BK = b43_setup_dmaring(dev, 0, 1, type);
-+ if (!dma->tx_ring_AC_BK)
- goto out;
-- dma->tx_ring0 = ring;
--
-- ring = b43_setup_dmaring(dev, 1, 1, type);
-- if (!ring)
-- goto err_destroy_tx0;
-- dma->tx_ring1 = ring;
--
-- ring = b43_setup_dmaring(dev, 2, 1, type);
-- if (!ring)
-- goto err_destroy_tx1;
-- dma->tx_ring2 = ring;
-
-- ring = b43_setup_dmaring(dev, 3, 1, type);
-- if (!ring)
-- goto err_destroy_tx2;
-- dma->tx_ring3 = ring;
-+ dma->tx_ring_AC_BE = b43_setup_dmaring(dev, 1, 1, type);
-+ if (!dma->tx_ring_AC_BE)
-+ goto err_destroy_bk;
-+
-+ dma->tx_ring_AC_VI = b43_setup_dmaring(dev, 2, 1, type);
-+ if (!dma->tx_ring_AC_VI)
-+ goto err_destroy_be;
-+
-+ dma->tx_ring_AC_VO = b43_setup_dmaring(dev, 3, 1, type);
-+ if (!dma->tx_ring_AC_VO)
-+ goto err_destroy_vi;
-+
-+ dma->tx_ring_mcast = b43_setup_dmaring(dev, 4, 1, type);
-+ if (!dma->tx_ring_mcast)
-+ goto err_destroy_vo;
-+
-+ /* setup RX DMA channel. */
-+ dma->rx_ring = b43_setup_dmaring(dev, 0, 0, type);
-+ if (!dma->rx_ring)
-+ goto err_destroy_mcast;
-
-- ring = b43_setup_dmaring(dev, 4, 1, type);
-- if (!ring)
-- goto err_destroy_tx3;
-- dma->tx_ring4 = ring;
--
-- ring = b43_setup_dmaring(dev, 5, 1, type);
-- if (!ring)
-- goto err_destroy_tx4;
-- dma->tx_ring5 = ring;
--
-- /* setup RX DMA channels. */
-- ring = b43_setup_dmaring(dev, 0, 0, type);
-- if (!ring)
-- goto err_destroy_tx5;
-- dma->rx_ring0 = ring;
--
-- if (dev->dev->id.revision < 5) {
-- ring = b43_setup_dmaring(dev, 3, 0, type);
-- if (!ring)
-- goto err_destroy_rx0;
-- dma->rx_ring3 = ring;
-- }
-+ /* No support for the TX status DMA ring. */
-+ B43_WARN_ON(dev->dev->id.revision < 5);
-
- b43dbg(dev->wl, "%u-bit DMA initialized\n",
- (unsigned int)type);
- err = 0;
-- out:
-+out:
- return err;
-
-- err_destroy_rx0:
-- b43_destroy_dmaring(dma->rx_ring0);
-- dma->rx_ring0 = NULL;
-- err_destroy_tx5:
-- b43_destroy_dmaring(dma->tx_ring5);
-- dma->tx_ring5 = NULL;
-- err_destroy_tx4:
-- b43_destroy_dmaring(dma->tx_ring4);
-- dma->tx_ring4 = NULL;
-- err_destroy_tx3:
-- b43_destroy_dmaring(dma->tx_ring3);
-- dma->tx_ring3 = NULL;
-- err_destroy_tx2:
-- b43_destroy_dmaring(dma->tx_ring2);
-- dma->tx_ring2 = NULL;
-- err_destroy_tx1:
-- b43_destroy_dmaring(dma->tx_ring1);
-- dma->tx_ring1 = NULL;
-- err_destroy_tx0:
-- b43_destroy_dmaring(dma->tx_ring0);
-- dma->tx_ring0 = NULL;
-- goto out;
-+err_destroy_mcast:
-+ destroy_ring(dma, tx_ring_mcast);
-+err_destroy_vo:
-+ destroy_ring(dma, tx_ring_AC_VO);
-+err_destroy_vi:
-+ destroy_ring(dma, tx_ring_AC_VI);
-+err_destroy_be:
-+ destroy_ring(dma, tx_ring_AC_BE);
-+err_destroy_bk:
-+ destroy_ring(dma, tx_ring_AC_BK);
-+ return err;
- }
-
- /* Generate a cookie for the TX header. */
- static u16 generate_cookie(struct b43_dmaring *ring, int slot)
- {
-- u16 cookie = 0x1000;
-+ u16 cookie;
-
- /* Use the upper 4 bits of the cookie as
- * DMA controller ID and store the slot number
-@@ -1101,30 +1060,9 @@
- * It can also not be 0xFFFF because that is special
- * for multicast frames.
- */
-- switch (ring->index) {
-- case 0:
-- cookie = 0x1000;
-- break;
-- case 1:
-- cookie = 0x2000;
-- break;
-- case 2:
-- cookie = 0x3000;
-- break;
-- case 3:
-- cookie = 0x4000;
-- break;
-- case 4:
-- cookie = 0x5000;
-- break;
-- case 5:
-- cookie = 0x6000;
-- break;
-- default:
-- B43_WARN_ON(1);
-- }
-+ cookie = (((u16)ring->index + 1) << 12);
- B43_WARN_ON(slot & ~0x0FFF);
-- cookie |= (u16) slot;
-+ cookie |= (u16)slot;
-
- return cookie;
- }
-@@ -1138,22 +1076,19 @@
-
- switch (cookie & 0xF000) {
- case 0x1000:
-- ring = dma->tx_ring0;
-+ ring = dma->tx_ring_AC_BK;
- break;
- case 0x2000:
-- ring = dma->tx_ring1;
-+ ring = dma->tx_ring_AC_BE;
- break;
- case 0x3000:
-- ring = dma->tx_ring2;
-+ ring = dma->tx_ring_AC_VI;
- break;
- case 0x4000:
-- ring = dma->tx_ring3;
-+ ring = dma->tx_ring_AC_VO;
- break;
- case 0x5000:
-- ring = dma->tx_ring4;
-- break;
-- case 0x6000:
-- ring = dma->tx_ring5;
-+ ring = dma->tx_ring_mcast;
- break;
- default:
- B43_WARN_ON(1);
-@@ -1180,7 +1115,6 @@
- size_t hdrsize = b43_txhdr_size(ring->dev);
-
- #define SLOTS_PER_PACKET 2
-- B43_WARN_ON(skb_shinfo(skb)->nr_frags);
-
- old_top_slot = ring->current_slot;
- old_used_slots = ring->used_slots;
-@@ -1285,6 +1219,37 @@
- return 0;
- }
-
-+/* Static mapping of mac80211's queues (priorities) to b43 DMA rings. */
-+static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
-+ u8 queue_prio)
-+{
-+ struct b43_dmaring *ring;
-+
-+ if (b43_modparam_qos) {
-+ /* 0 = highest priority */
-+ switch (queue_prio) {
-+ default:
-+ B43_WARN_ON(1);
-+ /* fallthrough */
-+ case 0:
-+ ring = dev->dma.tx_ring_AC_VO;
-+ break;
-+ case 1:
-+ ring = dev->dma.tx_ring_AC_VI;
-+ break;
-+ case 2:
-+ ring = dev->dma.tx_ring_AC_BE;
-+ break;
-+ case 3:
-+ ring = dev->dma.tx_ring_AC_BK;
-+ break;
-+ }
-+ } else
-+ ring = dev->dma.tx_ring_AC_BE;
-+
-+ return ring;
-+}
-+
- int b43_dma_tx(struct b43_wldev *dev,
- struct sk_buff *skb, struct ieee80211_tx_control *ctl)
- {
-@@ -1293,21 +1258,16 @@
- int err = 0;
- unsigned long flags;
-
-- if (unlikely(skb->len < 2 + 2 + 6)) {
-- /* Too short, this can't be a valid frame. */
-- return -EINVAL;
-- }
--
- hdr = (struct ieee80211_hdr *)skb->data;
- if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
- /* The multicast ring will be sent after the DTIM */
-- ring = dev->dma.tx_ring4;
-+ ring = dev->dma.tx_ring_mcast;
- /* Set the more-data bit. Ucode will clear it on
- * the last frame for us. */
- hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
- } else {
- /* Decide by priority where to put this frame. */
-- ring = priority_to_txring(dev, ctl->queue);
-+ ring = select_ring_by_priority(dev, ctl->queue);
- }
-
- spin_lock_irqsave(&ring->lock, flags);
-@@ -1322,6 +1282,11 @@
- * That would be a mac80211 bug. */
- B43_WARN_ON(ring->stopped);
-
-+ /* Assign the queue number to the ring (if not already done before)
-+ * so TX status handling can use it. The queue to ring mapping is
-+ * static, so we don't need to store it per frame. */
-+ ring->queue_prio = ctl->queue;
-+
- err = dma_tx_fragment(ring, skb, ctl);
- if (unlikely(err == -ENOKEY)) {
- /* Drop this packet, as we don't have the encryption key
-@@ -1338,7 +1303,7 @@
- if ((free_slots(ring) < SLOTS_PER_PACKET) ||
- should_inject_overflow(ring)) {
- /* This TX ring is full. */
-- ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring));
-+ ieee80211_stop_queue(dev->wl->hw, ctl->queue);
- ring->stopped = 1;
- if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
- b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
-@@ -1359,6 +1324,7 @@
- struct b43_dmadesc_generic *desc;
- struct b43_dmadesc_meta *meta;
- int slot;
-+ bool frame_succeed;
-
- ring = parse_cookie(dev, status->cookie, &slot);
- if (unlikely(!ring))
-@@ -1385,18 +1351,15 @@
- * status of the transmission.
- * Some fields of txstat are already filled in dma_tx().
- */
-- if (status->acked) {
-- meta->txstat.flags |= IEEE80211_TX_STATUS_ACK;
-- } else {
-- if (!(meta->txstat.control.flags
-- & IEEE80211_TXCTL_NO_ACK))
-- meta->txstat.excessive_retries = 1;
-- }
-- if (status->frame_count == 0) {
-- /* The frame was not transmitted at all. */
-- meta->txstat.retry_count = 0;
-- } else
-- meta->txstat.retry_count = status->frame_count - 1;
-+ frame_succeed = b43_fill_txstatus_report(
-+ &(meta->txstat), status);
-+#ifdef CONFIG_B43_DEBUG
-+ if (frame_succeed)
-+ ring->nr_succeed_tx_packets++;
-+ else
-+ ring->nr_failed_tx_packets++;
-+ ring->nr_total_packet_tries += status->frame_count;
-+#endif /* DEBUG */
- ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
- &(meta->txstat));
- /* skb is freed by ieee80211_tx_status_irqsafe() */
-@@ -1418,7 +1381,7 @@
- dev->stats.last_tx = jiffies;
- if (ring->stopped) {
- B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
-- ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring));
-+ ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
- ring->stopped = 0;
- if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
- b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
-@@ -1439,7 +1402,7 @@
-
- for (i = 0; i < nr_queues; i++) {
- data = &(stats->data[i]);
-- ring = priority_to_txring(dev, i);
-+ ring = select_ring_by_priority(dev, i);
-
- spin_lock_irqsave(&ring->lock, flags);
- data->len = ring->used_slots / SLOTS_PER_PACKET;
-@@ -1465,25 +1428,6 @@
- sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
- skb = meta->skb;
-
-- if (ring->index == 3) {
-- /* We received an xmit status. */
-- struct b43_hwtxstatus *hw = (struct b43_hwtxstatus *)skb->data;
-- int i = 0;
--
-- while (hw->cookie == 0) {
-- if (i > 100)
-- break;
-- i++;
-- udelay(2);
-- barrier();
-- }
-- b43_handle_hwtxstatus(ring->dev, hw);
-- /* recycle the descriptor buffer. */
-- sync_descbuffer_for_device(ring, meta->dmaaddr,
-- ring->rx_buffersize);
--
-- return;
-- }
- rxhdr = (struct b43_rxhdr_fw4 *)skb->data;
- len = le16_to_cpu(rxhdr->frame_len);
- if (len == 0) {
-@@ -1540,7 +1484,7 @@
- skb_pull(skb, ring->frameoffset);
-
- b43_rx(ring->dev, skb, rxhdr);
-- drop:
-+drop:
- return;
- }
-
-@@ -1586,21 +1530,55 @@
- void b43_dma_tx_suspend(struct b43_wldev *dev)
- {
- b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
-- b43_dma_tx_suspend_ring(dev->dma.tx_ring0);
-- b43_dma_tx_suspend_ring(dev->dma.tx_ring1);
-- b43_dma_tx_suspend_ring(dev->dma.tx_ring2);
-- b43_dma_tx_suspend_ring(dev->dma.tx_ring3);
-- b43_dma_tx_suspend_ring(dev->dma.tx_ring4);
-- b43_dma_tx_suspend_ring(dev->dma.tx_ring5);
-+ b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_BK);
-+ b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_BE);
-+ b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_VI);
-+ b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_VO);
-+ b43_dma_tx_suspend_ring(dev->dma.tx_ring_mcast);
- }
-
- void b43_dma_tx_resume(struct b43_wldev *dev)
- {
-- b43_dma_tx_resume_ring(dev->dma.tx_ring5);
-- b43_dma_tx_resume_ring(dev->dma.tx_ring4);
-- b43_dma_tx_resume_ring(dev->dma.tx_ring3);
-- b43_dma_tx_resume_ring(dev->dma.tx_ring2);
-- b43_dma_tx_resume_ring(dev->dma.tx_ring1);
-- b43_dma_tx_resume_ring(dev->dma.tx_ring0);
-+ b43_dma_tx_resume_ring(dev->dma.tx_ring_mcast);
-+ b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_VO);
-+ b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_VI);
-+ b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_BE);
-+ b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_BK);
- b43_power_saving_ctl_bits(dev, 0);
- }
-+
-+#ifdef CONFIG_B43_PIO
-+static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type,
-+ u16 mmio_base, bool enable)
-+{
-+ u32 ctl;
-+
-+ if (type == B43_DMA_64BIT) {
-+ ctl = b43_read32(dev, mmio_base + B43_DMA64_RXCTL);
-+ ctl &= ~B43_DMA64_RXDIRECTFIFO;
-+ if (enable)
-+ ctl |= B43_DMA64_RXDIRECTFIFO;
-+ b43_write32(dev, mmio_base + B43_DMA64_RXCTL, ctl);
-+ } else {
-+ ctl = b43_read32(dev, mmio_base + B43_DMA32_RXCTL);
-+ ctl &= ~B43_DMA32_RXDIRECTFIFO;
-+ if (enable)
-+ ctl |= B43_DMA32_RXDIRECTFIFO;
-+ b43_write32(dev, mmio_base + B43_DMA32_RXCTL, ctl);
-+ }
-+}
-+
-+/* Enable/Disable Direct FIFO Receive Mode (PIO) on a RX engine.
-+ * This is called from PIO code, so DMA structures are not available. */
-+void b43_dma_direct_fifo_rx(struct b43_wldev *dev,
-+ unsigned int engine_index, bool enable)
-+{
-+ enum b43_dmatype type;
-+ u16 mmio_base;
-+
-+ type = dma_mask_to_engine_type(supported_dma_mask(dev));
-+
-+ mmio_base = b43_dmacontroller_base(type, engine_index);
-+ direct_fifo_rx(dev, type, mmio_base, enable);
-+}
-+#endif /* CONFIG_B43_PIO */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/dma.h linux-2.6.25/drivers/net/wireless/b43/dma.h
---- linux-2.6.25.old/drivers/net/wireless/b43/dma.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/dma.h 2008-04-19 13:54:59.000000000 +0200
-@@ -245,6 +245,9 @@
- enum b43_dmatype type;
- /* Boolean. Is this ring stopped at ieee80211 level? */
- bool stopped;
-+ /* The QOS priority assigned to this ring. Only used for TX rings.
-+ * This is the mac80211 "queue" value. */
-+ u8 queue_prio;
- /* Lock, only used for TX. */
- spinlock_t lock;
- struct b43_wldev *dev;
-@@ -253,6 +256,12 @@
- int max_used_slots;
- /* Last time we injected a ring overflow. */
- unsigned long last_injected_overflow;
-+ /* Statistics: Number of successfully transmitted packets */
-+ u64 nr_succeed_tx_packets;
-+ /* Statistics: Number of failed TX packets */
-+ u64 nr_failed_tx_packets;
-+ /* Statistics: Total number of TX plus all retries. */
-+ u64 nr_total_packet_tries;
- #endif /* CONFIG_B43_DEBUG */
- };
-
-@@ -282,4 +291,7 @@
-
- void b43_dma_rx(struct b43_dmaring *ring);
-
-+void b43_dma_direct_fifo_rx(struct b43_wldev *dev,
-+ unsigned int engine_index, bool enable);
-+
- #endif /* B43_DMA_H_ */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/Kconfig linux-2.6.25/drivers/net/wireless/b43/Kconfig
---- linux-2.6.25.old/drivers/net/wireless/b43/Kconfig 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/Kconfig 2008-04-19 13:54:59.000000000 +0200
-@@ -62,6 +62,14 @@
-
- If unsure, say N.
-
-+# Data transfers to the device via PIO
-+# This is only needed on PCMCIA devices. All others can do DMA properly.
-+config B43_PIO
-+ bool
-+ depends on B43 && (B43_PCMCIA || B43_FORCE_PIO)
-+ select SSB_BLOCKIO
-+ default y
-+
- config B43_NPHY
- bool "Pre IEEE 802.11n support (BROKEN)"
- depends on B43 && EXPERIMENTAL && BROKEN
-@@ -94,3 +102,13 @@
-
- Say Y, if you want to find out why the driver does not
- work for you.
-+
-+config B43_FORCE_PIO
-+ bool "Force usage of PIO instead of DMA"
-+ depends on B43 && B43_DEBUG
-+ ---help---
-+ This will disable DMA and always enable PIO instead.
-+
-+ Say N!
-+ This is only for debugging the PIO engine code. You do
-+ _NOT_ want to enable this.
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/main.c linux-2.6.25/drivers/net/wireless/b43/main.c
---- linux-2.6.25.old/drivers/net/wireless/b43/main.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/main.c 2008-04-19 13:54:59.000000000 +0200
-@@ -46,7 +46,9 @@
- #include "main.h"
- #include "debugfs.h"
- #include "phy.h"
-+#include "nphy.h"
- #include "dma.h"
-+#include "pio.h"
- #include "sysfs.h"
- #include "xmit.h"
- #include "lo.h"
-@@ -78,6 +80,11 @@
- module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
- MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-
-+int b43_modparam_qos = 1;
-+module_param_named(qos, b43_modparam_qos, int, 0444);
-+MODULE_PARM_DESC(qos, "Enable QOS support (default on)");
-+
-+
- static const struct ssb_device_id b43_ssb_tbl[] = {
- SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
- SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6),
-@@ -97,24 +104,28 @@
- * get concurrency issues */
- #define RATETAB_ENT(_rateid, _flags) \
- { \
-- .rate = B43_RATE_TO_BASE100KBPS(_rateid), \
-- .val = (_rateid), \
-- .val2 = (_rateid), \
-+ .bitrate = B43_RATE_TO_BASE100KBPS(_rateid), \
-+ .hw_value = (_rateid), \
- .flags = (_flags), \
- }
-+
-+/*
-+ * NOTE: When changing this, sync with xmit.c's
-+ * b43_plcp_get_bitrate_idx_* functions!
-+ */
- static struct ieee80211_rate __b43_ratetable[] = {
-- RATETAB_ENT(B43_CCK_RATE_1MB, IEEE80211_RATE_CCK),
-- RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_CCK_2),
-- RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_CCK_2),
-- RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_CCK_2),
-- RATETAB_ENT(B43_OFDM_RATE_6MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43_OFDM_RATE_9MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43_OFDM_RATE_12MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43_OFDM_RATE_18MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43_OFDM_RATE_24MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43_OFDM_RATE_36MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43_OFDM_RATE_48MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43_OFDM_RATE_54MB, IEEE80211_RATE_OFDM),
-+ RATETAB_ENT(B43_CCK_RATE_1MB, 0),
-+ RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE),
-+ RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE),
-+ RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE),
-+ RATETAB_ENT(B43_OFDM_RATE_6MB, 0),
-+ RATETAB_ENT(B43_OFDM_RATE_9MB, 0),
-+ RATETAB_ENT(B43_OFDM_RATE_12MB, 0),
-+ RATETAB_ENT(B43_OFDM_RATE_18MB, 0),
-+ RATETAB_ENT(B43_OFDM_RATE_24MB, 0),
-+ RATETAB_ENT(B43_OFDM_RATE_36MB, 0),
-+ RATETAB_ENT(B43_OFDM_RATE_48MB, 0),
-+ RATETAB_ENT(B43_OFDM_RATE_54MB, 0),
- };
-
- #define b43_a_ratetable (__b43_ratetable + 4)
-@@ -124,53 +135,144 @@
- #define b43_g_ratetable (__b43_ratetable + 0)
- #define b43_g_ratetable_size 12
-
--#define CHANTAB_ENT(_chanid, _freq) \
-- { \
-- .chan = (_chanid), \
-- .freq = (_freq), \
-- .val = (_chanid), \
-- .flag = IEEE80211_CHAN_W_SCAN | \
-- IEEE80211_CHAN_W_ACTIVE_SCAN | \
-- IEEE80211_CHAN_W_IBSS, \
-- .power_level = 0xFF, \
-- .antenna_max = 0xFF, \
-- }
-+#define CHAN4G(_channel, _freq, _flags) { \
-+ .band = IEEE80211_BAND_2GHZ, \
-+ .center_freq = (_freq), \
-+ .hw_value = (_channel), \
-+ .flags = (_flags), \
-+ .max_antenna_gain = 0, \
-+ .max_power = 30, \
-+}
- static struct ieee80211_channel b43_2ghz_chantable[] = {
-- CHANTAB_ENT(1, 2412),
-- CHANTAB_ENT(2, 2417),
-- CHANTAB_ENT(3, 2422),
-- CHANTAB_ENT(4, 2427),
-- CHANTAB_ENT(5, 2432),
-- CHANTAB_ENT(6, 2437),
-- CHANTAB_ENT(7, 2442),
-- CHANTAB_ENT(8, 2447),
-- CHANTAB_ENT(9, 2452),
-- CHANTAB_ENT(10, 2457),
-- CHANTAB_ENT(11, 2462),
-- CHANTAB_ENT(12, 2467),
-- CHANTAB_ENT(13, 2472),
-- CHANTAB_ENT(14, 2484),
-+ CHAN4G(1, 2412, 0),
-+ CHAN4G(2, 2417, 0),
-+ CHAN4G(3, 2422, 0),
-+ CHAN4G(4, 2427, 0),
-+ CHAN4G(5, 2432, 0),
-+ CHAN4G(6, 2437, 0),
-+ CHAN4G(7, 2442, 0),
-+ CHAN4G(8, 2447, 0),
-+ CHAN4G(9, 2452, 0),
-+ CHAN4G(10, 2457, 0),
-+ CHAN4G(11, 2462, 0),
-+ CHAN4G(12, 2467, 0),
-+ CHAN4G(13, 2472, 0),
-+ CHAN4G(14, 2484, 0),
-+};
-+#undef CHAN4G
-+
-+#define CHAN5G(_channel, _flags) { \
-+ .band = IEEE80211_BAND_5GHZ, \
-+ .center_freq = 5000 + (5 * (_channel)), \
-+ .hw_value = (_channel), \
-+ .flags = (_flags), \
-+ .max_antenna_gain = 0, \
-+ .max_power = 30, \
-+}
-+static struct ieee80211_channel b43_5ghz_nphy_chantable[] = {
-+ CHAN5G(32, 0), CHAN5G(34, 0),
-+ CHAN5G(36, 0), CHAN5G(38, 0),
-+ CHAN5G(40, 0), CHAN5G(42, 0),
-+ CHAN5G(44, 0), CHAN5G(46, 0),
-+ CHAN5G(48, 0), CHAN5G(50, 0),
-+ CHAN5G(52, 0), CHAN5G(54, 0),
-+ CHAN5G(56, 0), CHAN5G(58, 0),
-+ CHAN5G(60, 0), CHAN5G(62, 0),
-+ CHAN5G(64, 0), CHAN5G(66, 0),
-+ CHAN5G(68, 0), CHAN5G(70, 0),
-+ CHAN5G(72, 0), CHAN5G(74, 0),
-+ CHAN5G(76, 0), CHAN5G(78, 0),
-+ CHAN5G(80, 0), CHAN5G(82, 0),
-+ CHAN5G(84, 0), CHAN5G(86, 0),
-+ CHAN5G(88, 0), CHAN5G(90, 0),
-+ CHAN5G(92, 0), CHAN5G(94, 0),
-+ CHAN5G(96, 0), CHAN5G(98, 0),
-+ CHAN5G(100, 0), CHAN5G(102, 0),
-+ CHAN5G(104, 0), CHAN5G(106, 0),
-+ CHAN5G(108, 0), CHAN5G(110, 0),
-+ CHAN5G(112, 0), CHAN5G(114, 0),
-+ CHAN5G(116, 0), CHAN5G(118, 0),
-+ CHAN5G(120, 0), CHAN5G(122, 0),
-+ CHAN5G(124, 0), CHAN5G(126, 0),
-+ CHAN5G(128, 0), CHAN5G(130, 0),
-+ CHAN5G(132, 0), CHAN5G(134, 0),
-+ CHAN5G(136, 0), CHAN5G(138, 0),
-+ CHAN5G(140, 0), CHAN5G(142, 0),
-+ CHAN5G(144, 0), CHAN5G(145, 0),
-+ CHAN5G(146, 0), CHAN5G(147, 0),
-+ CHAN5G(148, 0), CHAN5G(149, 0),
-+ CHAN5G(150, 0), CHAN5G(151, 0),
-+ CHAN5G(152, 0), CHAN5G(153, 0),
-+ CHAN5G(154, 0), CHAN5G(155, 0),
-+ CHAN5G(156, 0), CHAN5G(157, 0),
-+ CHAN5G(158, 0), CHAN5G(159, 0),
-+ CHAN5G(160, 0), CHAN5G(161, 0),
-+ CHAN5G(162, 0), CHAN5G(163, 0),
-+ CHAN5G(164, 0), CHAN5G(165, 0),
-+ CHAN5G(166, 0), CHAN5G(168, 0),
-+ CHAN5G(170, 0), CHAN5G(172, 0),
-+ CHAN5G(174, 0), CHAN5G(176, 0),
-+ CHAN5G(178, 0), CHAN5G(180, 0),
-+ CHAN5G(182, 0), CHAN5G(184, 0),
-+ CHAN5G(186, 0), CHAN5G(188, 0),
-+ CHAN5G(190, 0), CHAN5G(192, 0),
-+ CHAN5G(194, 0), CHAN5G(196, 0),
-+ CHAN5G(198, 0), CHAN5G(200, 0),
-+ CHAN5G(202, 0), CHAN5G(204, 0),
-+ CHAN5G(206, 0), CHAN5G(208, 0),
-+ CHAN5G(210, 0), CHAN5G(212, 0),
-+ CHAN5G(214, 0), CHAN5G(216, 0),
-+ CHAN5G(218, 0), CHAN5G(220, 0),
-+ CHAN5G(222, 0), CHAN5G(224, 0),
-+ CHAN5G(226, 0), CHAN5G(228, 0),
- };
--#define b43_2ghz_chantable_size ARRAY_SIZE(b43_2ghz_chantable)
-
--#if 0
--static struct ieee80211_channel b43_5ghz_chantable[] = {
-- CHANTAB_ENT(36, 5180),
-- CHANTAB_ENT(40, 5200),
-- CHANTAB_ENT(44, 5220),
-- CHANTAB_ENT(48, 5240),
-- CHANTAB_ENT(52, 5260),
-- CHANTAB_ENT(56, 5280),
-- CHANTAB_ENT(60, 5300),
-- CHANTAB_ENT(64, 5320),
-- CHANTAB_ENT(149, 5745),
-- CHANTAB_ENT(153, 5765),
-- CHANTAB_ENT(157, 5785),
-- CHANTAB_ENT(161, 5805),
-- CHANTAB_ENT(165, 5825),
-+static struct ieee80211_channel b43_5ghz_aphy_chantable[] = {
-+ CHAN5G(34, 0), CHAN5G(36, 0),
-+ CHAN5G(38, 0), CHAN5G(40, 0),
-+ CHAN5G(42, 0), CHAN5G(44, 0),
-+ CHAN5G(46, 0), CHAN5G(48, 0),
-+ CHAN5G(52, 0), CHAN5G(56, 0),
-+ CHAN5G(60, 0), CHAN5G(64, 0),
-+ CHAN5G(100, 0), CHAN5G(104, 0),
-+ CHAN5G(108, 0), CHAN5G(112, 0),
-+ CHAN5G(116, 0), CHAN5G(120, 0),
-+ CHAN5G(124, 0), CHAN5G(128, 0),
-+ CHAN5G(132, 0), CHAN5G(136, 0),
-+ CHAN5G(140, 0), CHAN5G(149, 0),
-+ CHAN5G(153, 0), CHAN5G(157, 0),
-+ CHAN5G(161, 0), CHAN5G(165, 0),
-+ CHAN5G(184, 0), CHAN5G(188, 0),
-+ CHAN5G(192, 0), CHAN5G(196, 0),
-+ CHAN5G(200, 0), CHAN5G(204, 0),
-+ CHAN5G(208, 0), CHAN5G(212, 0),
-+ CHAN5G(216, 0),
-+};
-+#undef CHAN5G
-+
-+static struct ieee80211_supported_band b43_band_5GHz_nphy = {
-+ .band = IEEE80211_BAND_5GHZ,
-+ .channels = b43_5ghz_nphy_chantable,
-+ .n_channels = ARRAY_SIZE(b43_5ghz_nphy_chantable),
-+ .bitrates = b43_a_ratetable,
-+ .n_bitrates = b43_a_ratetable_size,
-+};
-+
-+static struct ieee80211_supported_band b43_band_5GHz_aphy = {
-+ .band = IEEE80211_BAND_5GHZ,
-+ .channels = b43_5ghz_aphy_chantable,
-+ .n_channels = ARRAY_SIZE(b43_5ghz_aphy_chantable),
-+ .bitrates = b43_a_ratetable,
-+ .n_bitrates = b43_a_ratetable_size,
-+};
-+
-+static struct ieee80211_supported_band b43_band_2GHz = {
-+ .band = IEEE80211_BAND_2GHZ,
-+ .channels = b43_2ghz_chantable,
-+ .n_channels = ARRAY_SIZE(b43_2ghz_chantable),
-+ .bitrates = b43_g_ratetable,
-+ .n_bitrates = b43_g_ratetable_size,
- };
--#define b43_5ghz_chantable_size ARRAY_SIZE(b43_5ghz_chantable)
--#endif
-
- static void b43_wireless_core_exit(struct b43_wldev *dev);
- static int b43_wireless_core_init(struct b43_wldev *dev);
-@@ -370,24 +472,30 @@
- }
-
- /* Read HostFlags */
--u32 b43_hf_read(struct b43_wldev * dev)
-+u64 b43_hf_read(struct b43_wldev * dev)
- {
-- u32 ret;
-+ u64 ret;
-
- ret = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI);
- ret <<= 16;
-+ ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFMI);
-+ ret <<= 16;
- ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO);
-
- return ret;
- }
-
- /* Write HostFlags */
--void b43_hf_write(struct b43_wldev *dev, u32 value)
-+void b43_hf_write(struct b43_wldev *dev, u64 value)
- {
-- b43_shm_write16(dev, B43_SHM_SHARED,
-- B43_SHM_SH_HOSTFLO, (value & 0x0000FFFF));
-- b43_shm_write16(dev, B43_SHM_SHARED,
-- B43_SHM_SH_HOSTFHI, ((value & 0xFFFF0000) >> 16));
-+ u16 lo, mi, hi;
-+
-+ lo = (value & 0x00000000FFFFULL);
-+ mi = (value & 0x0000FFFF0000ULL) >> 16;
-+ hi = (value & 0xFFFF00000000ULL) >> 32;
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO, lo);
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFMI, mi);
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi);
- }
-
- void b43_tsf_read(struct b43_wldev *dev, u64 * tsf)
-@@ -912,7 +1020,18 @@
- /* Turn the Analog ON/OFF */
- static void b43_switch_analog(struct b43_wldev *dev, int on)
- {
-+ switch (dev->phy.type) {
-+ case B43_PHYTYPE_A:
-+ case B43_PHYTYPE_G:
- b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
-+ break;
-+ case B43_PHYTYPE_N:
-+ b43_phy_write(dev, B43_NPHY_AFECTL_OVER,
-+ on ? 0 : 0x7FFF);
-+ break;
-+ default:
-+ B43_WARN_ON(1);
-+ }
- }
-
- void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
-@@ -1162,22 +1281,107 @@
- size + sizeof(struct b43_plcp_hdr6));
- }
-
-+/* Check if the use of the antenna that ieee80211 told us to
-+ * use is possible. This will fall back to DEFAULT.
-+ * "antenna_nr" is the antenna identifier we got from ieee80211. */
-+u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,
-+ u8 antenna_nr)
-+{
-+ u8 antenna_mask;
-+
-+ if (antenna_nr == 0) {
-+ /* Zero means "use default antenna". That's always OK. */
-+ return 0;
-+ }
-+
-+ /* Get the mask of available antennas. */
-+ if (dev->phy.gmode)
-+ antenna_mask = dev->dev->bus->sprom.ant_available_bg;
-+ else
-+ antenna_mask = dev->dev->bus->sprom.ant_available_a;
-+
-+ if (!(antenna_mask & (1 << (antenna_nr - 1)))) {
-+ /* This antenna is not available. Fall back to default. */
-+ return 0;
-+ }
-+
-+ return antenna_nr;
-+}
-+
-+static int b43_antenna_from_ieee80211(struct b43_wldev *dev, u8 antenna)
-+{
-+ antenna = b43_ieee80211_antenna_sanitize(dev, antenna);
-+ switch (antenna) {
-+ case 0: /* default/diversity */
-+ return B43_ANTENNA_DEFAULT;
-+ case 1: /* Antenna 0 */
-+ return B43_ANTENNA0;
-+ case 2: /* Antenna 1 */
-+ return B43_ANTENNA1;
-+ case 3: /* Antenna 2 */
-+ return B43_ANTENNA2;
-+ case 4: /* Antenna 3 */
-+ return B43_ANTENNA3;
-+ default:
-+ return B43_ANTENNA_DEFAULT;
-+ }
-+}
-+
-+/* Convert a b43 antenna number value to the PHY TX control value. */
-+static u16 b43_antenna_to_phyctl(int antenna)
-+{
-+ switch (antenna) {
-+ case B43_ANTENNA0:
-+ return B43_TXH_PHY_ANT0;
-+ case B43_ANTENNA1:
-+ return B43_TXH_PHY_ANT1;
-+ case B43_ANTENNA2:
-+ return B43_TXH_PHY_ANT2;
-+ case B43_ANTENNA3:
-+ return B43_TXH_PHY_ANT3;
-+ case B43_ANTENNA_AUTO:
-+ return B43_TXH_PHY_ANT01AUTO;
-+ }
-+ B43_WARN_ON(1);
-+ return 0;
-+}
-+
- static void b43_write_beacon_template(struct b43_wldev *dev,
- u16 ram_offset,
-- u16 shm_size_offset, u8 rate)
-+ u16 shm_size_offset)
- {
- unsigned int i, len, variable_len;
- const struct ieee80211_mgmt *bcn;
- const u8 *ie;
- bool tim_found = 0;
-+ unsigned int rate;
-+ u16 ctl;
-+ int antenna;
-
- bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
- len = min((size_t) dev->wl->current_beacon->len,
- 0x200 - sizeof(struct b43_plcp_hdr6));
-+ rate = dev->wl->beacon_txctl.tx_rate->hw_value;
-
- b43_write_template_common(dev, (const u8 *)bcn,
- len, ram_offset, shm_size_offset, rate);
-
-+ /* Write the PHY TX control parameters. */
-+ antenna = b43_antenna_from_ieee80211(dev,
-+ dev->wl->beacon_txctl.antenna_sel_tx);
-+ antenna = b43_antenna_to_phyctl(antenna);
-+ ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
-+ /* We can't send beacons with short preamble. Would get PHY errors. */
-+ ctl &= ~B43_TXH_PHY_SHORTPRMBL;
-+ ctl &= ~B43_TXH_PHY_ANT;
-+ ctl &= ~B43_TXH_PHY_ENC;
-+ ctl |= antenna;
-+ if (b43_is_cck_rate(rate))
-+ ctl |= B43_TXH_PHY_ENC_CCK;
-+ else
-+ ctl |= B43_TXH_PHY_ENC_OFDM;
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL, ctl);
-+
- /* Find the position of the TIM and the DTIM_period value
- * and write them to SHM. */
- ie = bcn->u.beacon.variable;
-@@ -1218,21 +1422,23 @@
- b43warn(dev->wl, "Did not find a valid TIM IE in "
- "the beacon template packet. AP or IBSS operation "
- "may be broken.\n");
-- }
-+ } else
-+ b43dbg(dev->wl, "Updated beacon template\n");
- }
-
- static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
-- u16 shm_offset, u16 size, u8 rate)
-+ u16 shm_offset, u16 size,
-+ struct ieee80211_rate *rate)
- {
- struct b43_plcp_hdr4 plcp;
- u32 tmp;
- __le16 dur;
-
- plcp.data = 0;
-- b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
-+ b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
- dur = ieee80211_generic_frame_duration(dev->wl->hw,
- dev->wl->vif, size,
-- B43_RATE_TO_BASE100KBPS(rate));
-+ rate);
- /* Write PLCP in two parts and timing for packet transfer */
- tmp = le32_to_cpu(plcp.data);
- b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF);
-@@ -1247,7 +1453,8 @@
- * 3) Stripping TIM
- */
- static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
-- u16 *dest_size, u8 rate)
-+ u16 *dest_size,
-+ struct ieee80211_rate *rate)
- {
- const u8 *src_data;
- u8 *dest_data;
-@@ -1292,7 +1499,7 @@
- IEEE80211_STYPE_PROBE_RESP);
- dur = ieee80211_generic_frame_duration(dev->wl->hw,
- dev->wl->vif, *dest_size,
-- B43_RATE_TO_BASE100KBPS(rate));
-+ rate);
- hdr->duration_id = dur;
-
- return dest_data;
-@@ -1300,7 +1507,8 @@
-
- static void b43_write_probe_resp_template(struct b43_wldev *dev,
- u16 ram_offset,
-- u16 shm_size_offset, u8 rate)
-+ u16 shm_size_offset,
-+ struct ieee80211_rate *rate)
- {
- const u8 *probe_resp_data;
- u16 size;
-@@ -1313,20 +1521,89 @@
- /* Looks like PLCP headers plus packet timings are stored for
- * all possible basic rates
- */
-- b43_write_probe_resp_plcp(dev, 0x31A, size, B43_CCK_RATE_1MB);
-- b43_write_probe_resp_plcp(dev, 0x32C, size, B43_CCK_RATE_2MB);
-- b43_write_probe_resp_plcp(dev, 0x33E, size, B43_CCK_RATE_5MB);
-- b43_write_probe_resp_plcp(dev, 0x350, size, B43_CCK_RATE_11MB);
-+ b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]);
-+ b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]);
-+ b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]);
-+ b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]);
-
- size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6));
- b43_write_template_common(dev, probe_resp_data,
-- size, ram_offset, shm_size_offset, rate);
-+ size, ram_offset, shm_size_offset,
-+ rate->hw_value);
- kfree(probe_resp_data);
- }
-
-+static void handle_irq_beacon(struct b43_wldev *dev)
-+{
-+ struct b43_wl *wl = dev->wl;
-+ u32 cmd, beacon0_valid, beacon1_valid;
-+
-+ if (!b43_is_mode(wl, IEEE80211_IF_TYPE_AP))
-+ return;
-+
-+ /* This is the bottom half of the asynchronous beacon update. */
-+
-+ /* Ignore interrupt in the future. */
-+ dev->irq_savedstate &= ~B43_IRQ_BEACON;
-+
-+ cmd = b43_read32(dev, B43_MMIO_MACCMD);
-+ beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
-+ beacon1_valid = (cmd & B43_MACCMD_BEACON1_VALID);
-+
-+ /* Schedule interrupt manually, if busy. */
-+ if (beacon0_valid && beacon1_valid) {
-+ b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
-+ dev->irq_savedstate |= B43_IRQ_BEACON;
-+ return;
-+ }
-+
-+ if (!beacon0_valid) {
-+ if (!wl->beacon0_uploaded) {
-+ b43_write_beacon_template(dev, 0x68, 0x18);
-+ b43_write_probe_resp_template(dev, 0x268, 0x4A,
-+ &__b43_ratetable[3]);
-+ wl->beacon0_uploaded = 1;
-+ }
-+ cmd = b43_read32(dev, B43_MMIO_MACCMD);
-+ cmd |= B43_MACCMD_BEACON0_VALID;
-+ b43_write32(dev, B43_MMIO_MACCMD, cmd);
-+ } else if (!beacon1_valid) {
-+ if (!wl->beacon1_uploaded) {
-+ b43_write_beacon_template(dev, 0x468, 0x1A);
-+ wl->beacon1_uploaded = 1;
-+ }
-+ cmd = b43_read32(dev, B43_MMIO_MACCMD);
-+ cmd |= B43_MACCMD_BEACON1_VALID;
-+ b43_write32(dev, B43_MMIO_MACCMD, cmd);
-+ }
-+}
-+
-+static void b43_beacon_update_trigger_work(struct work_struct *work)
-+{
-+ struct b43_wl *wl = container_of(work, struct b43_wl,
-+ beacon_update_trigger);
-+ struct b43_wldev *dev;
-+
-+ mutex_lock(&wl->mutex);
-+ dev = wl->current_dev;
-+ if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
-+ spin_lock_irq(&wl->irq_lock);
-+ /* update beacon right away or defer to irq */
-+ dev->irq_savedstate = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
-+ handle_irq_beacon(dev);
-+ /* The handler might have updated the IRQ mask. */
-+ b43_write32(dev, B43_MMIO_GEN_IRQ_MASK,
-+ dev->irq_savedstate);
-+ mmiowb();
-+ spin_unlock_irq(&wl->irq_lock);
-+ }
-+ mutex_unlock(&wl->mutex);
-+}
-+
- /* Asynchronously update the packet templates in template RAM.
- * Locking: Requires wl->irq_lock to be locked. */
--static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon)
-+static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon,
-+ const struct ieee80211_tx_control *txctl)
- {
- /* This is the top half of the ansynchronous beacon update.
- * The bottom half is the beacon IRQ.
-@@ -1337,8 +1614,10 @@
- if (wl->current_beacon)
- dev_kfree_skb_any(wl->current_beacon);
- wl->current_beacon = beacon;
-+ memcpy(&wl->beacon_txctl, txctl, sizeof(wl->beacon_txctl));
- wl->beacon0_uploaded = 0;
- wl->beacon1_uploaded = 0;
-+ queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
- }
-
- static void b43_set_ssid(struct b43_wldev *dev, const u8 * ssid, u8 ssid_len)
-@@ -1364,44 +1643,14 @@
- {
- b43_time_lock(dev);
- if (dev->dev->id.revision >= 3) {
-- b43_write32(dev, 0x188, (beacon_int << 16));
-+ b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16));
-+ b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10));
- } else {
- b43_write16(dev, 0x606, (beacon_int >> 6));
- b43_write16(dev, 0x610, beacon_int);
- }
- b43_time_unlock(dev);
--}
--
--static void handle_irq_beacon(struct b43_wldev *dev)
--{
-- struct b43_wl *wl = dev->wl;
-- u32 cmd;
--
-- if (!b43_is_mode(wl, IEEE80211_IF_TYPE_AP))
-- return;
--
-- /* This is the bottom half of the asynchronous beacon update. */
--
-- cmd = b43_read32(dev, B43_MMIO_MACCMD);
-- if (!(cmd & B43_MACCMD_BEACON0_VALID)) {
-- if (!wl->beacon0_uploaded) {
-- b43_write_beacon_template(dev, 0x68, 0x18,
-- B43_CCK_RATE_1MB);
-- b43_write_probe_resp_template(dev, 0x268, 0x4A,
-- B43_CCK_RATE_11MB);
-- wl->beacon0_uploaded = 1;
-- }
-- cmd |= B43_MACCMD_BEACON0_VALID;
-- }
-- if (!(cmd & B43_MACCMD_BEACON1_VALID)) {
-- if (!wl->beacon1_uploaded) {
-- b43_write_beacon_template(dev, 0x468, 0x1A,
-- B43_CCK_RATE_1MB);
-- wl->beacon1_uploaded = 1;
-- }
-- cmd |= B43_MACCMD_BEACON1_VALID;
-- }
-- b43_write32(dev, B43_MMIO_MACCMD, cmd);
-+ b43dbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
- }
-
- static void handle_irq_ucode_debug(struct b43_wldev *dev)
-@@ -1483,12 +1732,15 @@
- handle_irq_noise(dev);
-
- /* Check the DMA reason registers for received data. */
-- if (dma_reason[0] & B43_DMAIRQ_RX_DONE)
-- b43_dma_rx(dev->dma.rx_ring0);
-- if (dma_reason[3] & B43_DMAIRQ_RX_DONE)
-- b43_dma_rx(dev->dma.rx_ring3);
-+ if (dma_reason[0] & B43_DMAIRQ_RX_DONE) {
-+ if (b43_using_pio_transfers(dev))
-+ b43_pio_rx(dev->pio.rx_queue);
-+ else
-+ b43_dma_rx(dev->dma.rx_ring);
-+ }
- B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE);
- B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE);
-+ B43_WARN_ON(dma_reason[3] & B43_DMAIRQ_RX_DONE);
- B43_WARN_ON(dma_reason[4] & B43_DMAIRQ_RX_DONE);
- B43_WARN_ON(dma_reason[5] & B43_DMAIRQ_RX_DONE);
-
-@@ -2045,7 +2297,7 @@
- }
-
- /* http://bcm-specs.sipsolutions.net/EnableMac */
--void b43_mac_enable(struct b43_wldev *dev)
-+static void b43_mac_enable(struct b43_wldev *dev)
- {
- dev->mac_suspended--;
- B43_WARN_ON(dev->mac_suspended < 0);
-@@ -2068,7 +2320,7 @@
- }
-
- /* http://bcm-specs.sipsolutions.net/SuspendMAC */
--void b43_mac_suspend(struct b43_wldev *dev)
-+static void b43_mac_suspend(struct b43_wldev *dev)
- {
- int i;
- u32 tmp;
-@@ -2091,6 +2343,13 @@
- & ~B43_MACCTL_ENABLED);
- /* force pci to flush the write */
- b43_read32(dev, B43_MMIO_MACCTL);
-+ for (i = 35; i; i--) {
-+ tmp = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
-+ if (tmp & B43_IRQ_MAC_SUSPENDED)
-+ goto out;
-+ udelay(10);
-+ }
-+ /* Hm, it seems this will take some time. Use msleep(). */
- for (i = 40; i; i--) {
- tmp = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
- if (tmp & B43_IRQ_MAC_SUSPENDED)
-@@ -2196,38 +2455,28 @@
- }
- }
-
-+/* Set the default values for the PHY TX Control Words. */
-+static void b43_set_phytxctl_defaults(struct b43_wldev *dev)
-+{
-+ u16 ctl = 0;
-+
-+ ctl |= B43_TXH_PHY_ENC_CCK;
-+ ctl |= B43_TXH_PHY_ANT01AUTO;
-+ ctl |= B43_TXH_PHY_TXPWR;
-+
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL, ctl);
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL, ctl);
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL, ctl);
-+}
-+
- /* Set the TX-Antenna for management frames sent by firmware. */
- static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
- {
-- u16 ant = 0;
-+ u16 ant;
- u16 tmp;
-
-- switch (antenna) {
-- case B43_ANTENNA0:
-- ant |= B43_TXH_PHY_ANT0;
-- break;
-- case B43_ANTENNA1:
-- ant |= B43_TXH_PHY_ANT1;
-- break;
-- case B43_ANTENNA2:
-- ant |= B43_TXH_PHY_ANT2;
-- break;
-- case B43_ANTENNA3:
-- ant |= B43_TXH_PHY_ANT3;
-- break;
-- case B43_ANTENNA_AUTO:
-- ant |= B43_TXH_PHY_ANT01AUTO;
-- break;
-- default:
-- B43_WARN_ON(1);
-- }
--
-- /* FIXME We also need to set the other flags of the PHY control field somewhere. */
-+ ant = b43_antenna_to_phyctl(antenna);
-
-- /* For Beacons */
-- tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
-- tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
-- b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL, tmp);
- /* For ACK/CTS */
- tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL);
- tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
-@@ -2589,11 +2838,20 @@
- struct b43_wldev *dev = wl->current_dev;
- int err = -ENODEV;
-
-+ if (unlikely(skb->len < 2 + 2 + 6)) {
-+ /* Too short, this can't be a valid frame. */
-+ return -EINVAL;
-+ }
-+ B43_WARN_ON(skb_shinfo(skb)->nr_frags);
-+
- if (unlikely(!dev))
- goto out;
- if (unlikely(b43_status(dev) < B43_STAT_STARTED))
- goto out;
-- /* DMA-TX is done without a global lock. */
-+ /* TX is done without a global lock. */
-+ if (b43_using_pio_transfers(dev))
-+ err = b43_pio_tx(dev, skb, ctl);
-+ else
- err = b43_dma_tx(dev, skb, ctl);
- out:
- if (unlikely(err))
-@@ -2601,10 +2859,178 @@
- return NETDEV_TX_OK;
- }
-
-+/* Locking: wl->irq_lock */
-+static void b43_qos_params_upload(struct b43_wldev *dev,
-+ const struct ieee80211_tx_queue_params *p,
-+ u16 shm_offset)
-+{
-+ u16 params[B43_NR_QOSPARAMS];
-+ int cw_min, cw_max, aifs, bslots, tmp;
-+ unsigned int i;
-+
-+ const u16 aCWmin = 0x0001;
-+ const u16 aCWmax = 0x03FF;
-+
-+ /* Calculate the default values for the parameters, if needed. */
-+ switch (shm_offset) {
-+ case B43_QOS_VOICE:
-+ aifs = (p->aifs == -1) ? 2 : p->aifs;
-+ cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 4 - 1) : p->cw_min;
-+ cw_max = (p->cw_max == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_max;
-+ break;
-+ case B43_QOS_VIDEO:
-+ aifs = (p->aifs == -1) ? 2 : p->aifs;
-+ cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_min;
-+ cw_max = (p->cw_max == 0) ? aCWmin : p->cw_max;
-+ break;
-+ case B43_QOS_BESTEFFORT:
-+ aifs = (p->aifs == -1) ? 3 : p->aifs;
-+ cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
-+ cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
-+ break;
-+ case B43_QOS_BACKGROUND:
-+ aifs = (p->aifs == -1) ? 7 : p->aifs;
-+ cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
-+ cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
-+ break;
-+ default:
-+ B43_WARN_ON(1);
-+ return;
-+ }
-+ if (cw_min <= 0)
-+ cw_min = aCWmin;
-+ if (cw_max <= 0)
-+ cw_max = aCWmin;
-+ bslots = b43_read16(dev, B43_MMIO_RNG) % cw_min;
-+
-+ memset(&params, 0, sizeof(params));
-+
-+ params[B43_QOSPARAM_TXOP] = p->txop * 32;
-+ params[B43_QOSPARAM_CWMIN] = cw_min;
-+ params[B43_QOSPARAM_CWMAX] = cw_max;
-+ params[B43_QOSPARAM_CWCUR] = cw_min;
-+ params[B43_QOSPARAM_AIFS] = aifs;
-+ params[B43_QOSPARAM_BSLOTS] = bslots;
-+ params[B43_QOSPARAM_REGGAP] = bslots + aifs;
-+
-+ for (i = 0; i < ARRAY_SIZE(params); i++) {
-+ if (i == B43_QOSPARAM_STATUS) {
-+ tmp = b43_shm_read16(dev, B43_SHM_SHARED,
-+ shm_offset + (i * 2));
-+ /* Mark the parameters as updated. */
-+ tmp |= 0x100;
-+ b43_shm_write16(dev, B43_SHM_SHARED,
-+ shm_offset + (i * 2),
-+ tmp);
-+ } else {
-+ b43_shm_write16(dev, B43_SHM_SHARED,
-+ shm_offset + (i * 2),
-+ params[i]);
-+ }
-+ }
-+}
-+
-+/* Update the QOS parameters in hardware. */
-+static void b43_qos_update(struct b43_wldev *dev)
-+{
-+ struct b43_wl *wl = dev->wl;
-+ struct b43_qos_params *params;
-+ unsigned long flags;
-+ unsigned int i;
-+
-+ /* Mapping of mac80211 queues to b43 SHM offsets. */
-+ static const u16 qos_shm_offsets[] = {
-+ [0] = B43_QOS_VOICE,
-+ [1] = B43_QOS_VIDEO,
-+ [2] = B43_QOS_BESTEFFORT,
-+ [3] = B43_QOS_BACKGROUND,
-+ };
-+ BUILD_BUG_ON(ARRAY_SIZE(qos_shm_offsets) != ARRAY_SIZE(wl->qos_params));
-+
-+ b43_mac_suspend(dev);
-+ spin_lock_irqsave(&wl->irq_lock, flags);
-+
-+ for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
-+ params = &(wl->qos_params[i]);
-+ if (params->need_hw_update) {
-+ b43_qos_params_upload(dev, &(params->p),
-+ qos_shm_offsets[i]);
-+ params->need_hw_update = 0;
-+ }
-+ }
-+
-+ spin_unlock_irqrestore(&wl->irq_lock, flags);
-+ b43_mac_enable(dev);
-+}
-+
-+static void b43_qos_clear(struct b43_wl *wl)
-+{
-+ struct b43_qos_params *params;
-+ unsigned int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
-+ params = &(wl->qos_params[i]);
-+
-+ memset(&(params->p), 0, sizeof(params->p));
-+ params->p.aifs = -1;
-+ params->need_hw_update = 1;
-+ }
-+}
-+
-+/* Initialize the core's QOS capabilities */
-+static void b43_qos_init(struct b43_wldev *dev)
-+{
-+ struct b43_wl *wl = dev->wl;
-+ unsigned int i;
-+
-+ /* Upload the current QOS parameters. */
-+ for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++)
-+ wl->qos_params[i].need_hw_update = 1;
-+ b43_qos_update(dev);
-+
-+ /* Enable QOS support. */
-+ b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
-+ b43_write16(dev, B43_MMIO_IFSCTL,
-+ b43_read16(dev, B43_MMIO_IFSCTL)
-+ | B43_MMIO_IFSCTL_USE_EDCF);
-+}
-+
-+static void b43_qos_update_work(struct work_struct *work)
-+{
-+ struct b43_wl *wl = container_of(work, struct b43_wl, qos_update_work);
-+ struct b43_wldev *dev;
-+
-+ mutex_lock(&wl->mutex);
-+ dev = wl->current_dev;
-+ if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED)))
-+ b43_qos_update(dev);
-+ mutex_unlock(&wl->mutex);
-+}
-+
- static int b43_op_conf_tx(struct ieee80211_hw *hw,
-- int queue,
-+ int _queue,
- const struct ieee80211_tx_queue_params *params)
- {
-+ struct b43_wl *wl = hw_to_b43_wl(hw);
-+ unsigned long flags;
-+ unsigned int queue = (unsigned int)_queue;
-+ struct b43_qos_params *p;
-+
-+ if (queue >= ARRAY_SIZE(wl->qos_params)) {
-+ /* Queue not available or don't support setting
-+ * params on this queue. Return success to not
-+ * confuse mac80211. */
-+ return 0;
-+ }
-+
-+ spin_lock_irqsave(&wl->irq_lock, flags);
-+ p = &(wl->qos_params[queue]);
-+ memcpy(&(p->p), params, sizeof(p->p));
-+ p->need_hw_update = 1;
-+ spin_unlock_irqrestore(&wl->irq_lock, flags);
-+
-+ queue_work(hw->workqueue, &wl->qos_update_work);
-+
- return 0;
- }
-
-@@ -2620,6 +3046,9 @@
- goto out;
- spin_lock_irqsave(&wl->irq_lock, flags);
- if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
-+ if (b43_using_pio_transfers(dev))
-+ b43_pio_get_tx_stats(dev, stats);
-+ else
- b43_dma_get_tx_stats(dev, stats);
- err = 0;
- }
-@@ -2641,45 +3070,6 @@
- return 0;
- }
-
--static const char *phymode_to_string(unsigned int phymode)
--{
-- switch (phymode) {
-- case B43_PHYMODE_A:
-- return "A";
-- case B43_PHYMODE_B:
-- return "B";
-- case B43_PHYMODE_G:
-- return "G";
-- default:
-- B43_WARN_ON(1);
-- }
-- return "";
--}
--
--static int find_wldev_for_phymode(struct b43_wl *wl,
-- unsigned int phymode,
-- struct b43_wldev **dev, bool * gmode)
--{
-- struct b43_wldev *d;
--
-- list_for_each_entry(d, &wl->devlist, list) {
-- if (d->phy.possible_phymodes & phymode) {
-- /* Ok, this device supports the PHY-mode.
-- * Now figure out how the gmode bit has to be
-- * set to support it. */
-- if (phymode == B43_PHYMODE_A)
-- *gmode = 0;
-- else
-- *gmode = 1;
-- *dev = d;
--
-- return 0;
-- }
-- }
--
-- return -ESRCH;
--}
--
- static void b43_put_phy_into_reset(struct b43_wldev *dev)
- {
- struct ssb_device *sdev = dev->dev;
-@@ -2699,28 +3089,64 @@
- msleep(1);
- }
-
-+static const char * band_to_string(enum ieee80211_band band)
-+{
-+ switch (band) {
-+ case IEEE80211_BAND_5GHZ:
-+ return "5";
-+ case IEEE80211_BAND_2GHZ:
-+ return "2.4";
-+ default:
-+ break;
-+ }
-+ B43_WARN_ON(1);
-+ return "";
-+}
-+
- /* Expects wl->mutex locked */
--static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode)
-+static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan)
- {
-- struct b43_wldev *up_dev;
-+ struct b43_wldev *up_dev = NULL;
- struct b43_wldev *down_dev;
-+ struct b43_wldev *d;
- int err;
-- bool gmode = 0;
-+ bool gmode;
- int prev_status;
-
-- err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode);
-- if (err) {
-- b43err(wl, "Could not find a device for %s-PHY mode\n",
-- phymode_to_string(new_mode));
-- return err;
-+ /* Find a device and PHY which supports the band. */
-+ list_for_each_entry(d, &wl->devlist, list) {
-+ switch (chan->band) {
-+ case IEEE80211_BAND_5GHZ:
-+ if (d->phy.supports_5ghz) {
-+ up_dev = d;
-+ gmode = 0;
-+ }
-+ break;
-+ case IEEE80211_BAND_2GHZ:
-+ if (d->phy.supports_2ghz) {
-+ up_dev = d;
-+ gmode = 1;
-+ }
-+ break;
-+ default:
-+ B43_WARN_ON(1);
-+ return -EINVAL;
-+ }
-+ if (up_dev)
-+ break;
-+ }
-+ if (!up_dev) {
-+ b43err(wl, "Could not find a device for %s-GHz band operation\n",
-+ band_to_string(chan->band));
-+ return -ENODEV;
- }
- if ((up_dev == wl->current_dev) &&
- (!!wl->current_dev->phy.gmode == !!gmode)) {
- /* This device is already running. */
- return 0;
- }
-- b43dbg(wl, "Reconfiguring PHYmode to %s-PHY\n",
-- phymode_to_string(new_mode));
-+ b43dbg(wl, "Switching to %s-GHz band\n",
-+ band_to_string(chan->band));
- down_dev = wl->current_dev;
-
- prev_status = b43_status(down_dev);
-@@ -2742,8 +3168,8 @@
- err = b43_wireless_core_init(up_dev);
- if (err) {
- b43err(wl, "Fatal: Could not initialize device for "
-- "newly selected %s-PHY mode\n",
-- phymode_to_string(new_mode));
-+ "selected %s-GHz band\n",
-+ band_to_string(chan->band));
- goto init_failure;
- }
- }
-@@ -2751,8 +3177,8 @@
- err = b43_wireless_core_start(up_dev);
- if (err) {
- b43err(wl, "Fatal: Coult not start device for "
-- "newly selected %s-PHY mode\n",
-- phymode_to_string(new_mode));
-+ "selected %s-GHz band\n",
-+ band_to_string(chan->band));
- b43_wireless_core_exit(up_dev);
- goto init_failure;
- }
-@@ -2762,86 +3188,26 @@
- wl->current_dev = up_dev;
-
- return 0;
-- init_failure:
-+init_failure:
- /* Whoops, failed to init the new core. No core is operating now. */
- wl->current_dev = NULL;
- return err;
- }
-
--/* Check if the use of the antenna that ieee80211 told us to
-- * use is possible. This will fall back to DEFAULT.
-- * "antenna_nr" is the antenna identifier we got from ieee80211. */
--u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,
-- u8 antenna_nr)
--{
-- u8 antenna_mask;
--
-- if (antenna_nr == 0) {
-- /* Zero means "use default antenna". That's always OK. */
-- return 0;
-- }
--
-- /* Get the mask of available antennas. */
-- if (dev->phy.gmode)
-- antenna_mask = dev->dev->bus->sprom.ant_available_bg;
-- else
-- antenna_mask = dev->dev->bus->sprom.ant_available_a;
--
-- if (!(antenna_mask & (1 << (antenna_nr - 1)))) {
-- /* This antenna is not available. Fall back to default. */
-- return 0;
-- }
--
-- return antenna_nr;
--}
--
--static int b43_antenna_from_ieee80211(struct b43_wldev *dev, u8 antenna)
--{
-- antenna = b43_ieee80211_antenna_sanitize(dev, antenna);
-- switch (antenna) {
-- case 0: /* default/diversity */
-- return B43_ANTENNA_DEFAULT;
-- case 1: /* Antenna 0 */
-- return B43_ANTENNA0;
-- case 2: /* Antenna 1 */
-- return B43_ANTENNA1;
-- case 3: /* Antenna 2 */
-- return B43_ANTENNA2;
-- case 4: /* Antenna 3 */
-- return B43_ANTENNA3;
-- default:
-- return B43_ANTENNA_DEFAULT;
-- }
--}
--
- static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
- {
- struct b43_wl *wl = hw_to_b43_wl(hw);
- struct b43_wldev *dev;
- struct b43_phy *phy;
- unsigned long flags;
-- unsigned int new_phymode = 0xFFFF;
- int antenna;
- int err = 0;
- u32 savedirqs;
-
- mutex_lock(&wl->mutex);
-
-- /* Switch the PHY mode (if necessary). */
-- switch (conf->phymode) {
-- case MODE_IEEE80211A:
-- new_phymode = B43_PHYMODE_A;
-- break;
-- case MODE_IEEE80211B:
-- new_phymode = B43_PHYMODE_B;
-- break;
-- case MODE_IEEE80211G:
-- new_phymode = B43_PHYMODE_G;
-- break;
-- default:
-- B43_WARN_ON(1);
-- }
-- err = b43_switch_phymode(wl, new_phymode);
-+ /* Switch the band (if necessary). This might change the active core. */
-+ err = b43_switch_band(wl, conf->channel);
- if (err)
- goto out_unlock_mutex;
- dev = wl->current_dev;
-@@ -2861,8 +3227,8 @@
-
- /* Switch to the requested channel.
- * The firmware takes care of races with the TX handler. */
-- if (conf->channel_val != phy->channel)
-- b43_radio_selectchannel(dev, conf->channel_val, 0);
-+ if (conf->channel->hw_value != phy->channel)
-+ b43_radio_selectchannel(dev, conf->channel->hw_value, 0);
-
- /* Enable/Disable ShortSlot timing. */
- if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) !=
-@@ -3075,8 +3441,10 @@
- if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP)) {
- B43_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP);
- b43_set_ssid(dev, conf->ssid, conf->ssid_len);
-- if (conf->beacon)
-- b43_update_templates(wl, conf->beacon);
-+ if (conf->beacon) {
-+ b43_update_templates(wl, conf->beacon,
-+ conf->beacon_control);
-+ }
- }
- b43_write_mac_bssid_templates(dev);
- }
-@@ -3106,6 +3474,7 @@
-
- b43_set_status(dev, B43_STAT_INITIALIZED);
-
-+ b43_pio_stop(dev);
- mutex_unlock(&wl->mutex);
- /* Must unlock as it would otherwise deadlock. No races here.
- * Cancel the possibly running self-rearming periodic work. */
-@@ -3400,6 +3769,41 @@
- long_retry);
- }
-
-+static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
-+{
-+ u16 pu_delay;
-+
-+ /* The time value is in microseconds. */
-+ if (dev->phy.type == B43_PHYTYPE_A)
-+ pu_delay = 3700;
-+ else
-+ pu_delay = 1050;
-+ if (b43_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS) || idle)
-+ pu_delay = 500;
-+ if ((dev->phy.radio_ver == 0x2050) && (dev->phy.radio_rev == 8))
-+ pu_delay = max(pu_delay, (u16)2400);
-+
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_SPUWKUP, pu_delay);
-+}
-+
-+/* Set the TSF CFP pre-TargetBeaconTransmissionTime. */
-+static void b43_set_pretbtt(struct b43_wldev *dev)
-+{
-+ u16 pretbtt;
-+
-+ /* The time value is in microseconds. */
-+ if (b43_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS)) {
-+ pretbtt = 2;
-+ } else {
-+ if (dev->phy.type == B43_PHYTYPE_A)
-+ pretbtt = 120;
-+ else
-+ pretbtt = 250;
-+ }
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRETBTT, pretbtt);
-+ b43_write16(dev, B43_MMIO_TSF_CFP_PRETBTT, pretbtt);
-+}
-+
- /* Shutdown a wireless core */
- /* Locking: wl->mutex */
- static void b43_wireless_core_exit(struct b43_wldev *dev)
-@@ -3423,6 +3827,7 @@
- b43_rng_exit(dev->wl, false);
- }
- b43_dma_free(dev);
-+ b43_pio_free(dev);
- b43_chip_exit(dev);
- b43_radio_turn_off(dev, 1);
- b43_switch_analog(dev, 0);
-@@ -3510,6 +3915,7 @@
- b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRMAXTIME, 1);
-
- b43_rate_memory_init(dev);
-+ b43_set_phytxctl_defaults(dev);
-
- /* Minimum Contention Window */
- if (phy->type == B43_PHYTYPE_B) {
-@@ -3520,18 +3926,17 @@
- /* Maximum Contention Window */
- b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
-
-+ if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || B43_FORCE_PIO) {
-+ dev->__using_pio_transfers = 1;
-+ err = b43_pio_init(dev);
-+ } else {
-+ dev->__using_pio_transfers = 0;
- err = b43_dma_init(dev);
-+ }
- if (err)
- goto err_chip_exit;
- b43_qos_init(dev);
--
--//FIXME
--#if 1
-- b43_write16(dev, 0x0612, 0x0050);
-- b43_shm_write16(dev, B43_SHM_SHARED, 0x0416, 0x0050);
-- b43_shm_write16(dev, B43_SHM_SHARED, 0x0414, 0x01F4);
--#endif
--
-+ b43_set_synth_pu_delay(dev, 1);
- b43_bluetooth_coext_enable(dev);
-
- ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
-@@ -3591,6 +3996,8 @@
-
- spin_lock_irqsave(&wl->irq_lock, flags);
- b43_adjust_opmode(dev);
-+ b43_set_pretbtt(dev);
-+ b43_set_synth_pu_delay(dev, 0);
- b43_upload_card_macaddress(dev);
- spin_unlock_irqrestore(&wl->irq_lock, flags);
-
-@@ -3642,6 +4049,7 @@
- memset(wl->mac_addr, 0, ETH_ALEN);
- wl->filter_flags = 0;
- wl->radiotap_enabled = 0;
-+ b43_qos_clear(wl);
-
- /* First register RFkill.
- * LEDs that are registered later depend on it. */
-@@ -3683,6 +4091,8 @@
- struct b43_wldev *dev = wl->current_dev;
-
- b43_rfkill_exit(dev);
-+ cancel_work_sync(&(wl->qos_update_work));
-+ cancel_work_sync(&(wl->beacon_update_trigger));
-
- mutex_lock(&wl->mutex);
- if (b43_status(dev) >= B43_STAT_STARTED)
-@@ -3716,16 +4126,17 @@
- struct b43_wl *wl = hw_to_b43_wl(hw);
- struct sk_buff *beacon;
- unsigned long flags;
-+ struct ieee80211_tx_control txctl;
-
- /* We could modify the existing beacon and set the aid bit in
- * the TIM field, but that would probably require resizing and
- * moving of data within the beacon template.
- * Simply request a new beacon and let mac80211 do the hard work. */
-- beacon = ieee80211_beacon_get(hw, wl->vif, NULL);
-+ beacon = ieee80211_beacon_get(hw, wl->vif, &txctl);
- if (unlikely(!beacon))
- return -ENOMEM;
- spin_lock_irqsave(&wl->irq_lock, flags);
-- b43_update_templates(wl, beacon);
-+ b43_update_templates(wl, beacon, &txctl);
- spin_unlock_irqrestore(&wl->irq_lock, flags);
-
- return 0;
-@@ -3739,12 +4150,22 @@
- unsigned long flags;
-
- spin_lock_irqsave(&wl->irq_lock, flags);
-- b43_update_templates(wl, beacon);
-+ b43_update_templates(wl, beacon, ctl);
- spin_unlock_irqrestore(&wl->irq_lock, flags);
-
- return 0;
- }
-
-+static void b43_op_sta_notify(struct ieee80211_hw *hw,
-+ struct ieee80211_vif *vif,
-+ enum sta_notify_cmd notify_cmd,
-+ const u8 *addr)
-+{
-+ struct b43_wl *wl = hw_to_b43_wl(hw);
-+
-+ B43_WARN_ON(!vif || wl->vif != vif);
-+}
-+
- static const struct ieee80211_ops b43_hw_ops = {
- .tx = b43_op_tx,
- .conf_tx = b43_op_conf_tx,
-@@ -3761,6 +4182,7 @@
- .set_retry_limit = b43_op_set_retry_limit,
- .set_tim = b43_op_beacon_set_tim,
- .beacon_update = b43_op_ibss_beacon_update,
-+ .sta_notify = b43_op_sta_notify,
- };
-
- /* Hard-reset the chip. Do not call this directly.
-@@ -3804,31 +4226,23 @@
- b43info(wl, "Controller restarted\n");
- }
-
--static int b43_setup_modes(struct b43_wldev *dev,
-+static int b43_setup_bands(struct b43_wldev *dev,
- bool have_2ghz_phy, bool have_5ghz_phy)
- {
- struct ieee80211_hw *hw = dev->wl->hw;
-- struct ieee80211_hw_mode *mode;
-- struct b43_phy *phy = &dev->phy;
-- int err;
-
-- /* XXX: This function will go away soon, when mac80211
-- * band stuff is rewritten. So this is just a hack.
-- * For now we always claim GPHY mode, as there is no
-- * support for NPHY and APHY in the device, yet.
-- * This assumption is OK, as any B, N or A PHY will already
-- * have died a horrible sanity check death earlier. */
--
-- mode = &phy->hwmodes[0];
-- mode->mode = MODE_IEEE80211G;
-- mode->num_channels = b43_2ghz_chantable_size;
-- mode->channels = b43_2ghz_chantable;
-- mode->num_rates = b43_g_ratetable_size;
-- mode->rates = b43_g_ratetable;
-- err = ieee80211_register_hwmode(hw, mode);
-- if (err)
-- return err;
-- phy->possible_phymodes |= B43_PHYMODE_G;
-+ if (have_2ghz_phy)
-+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
-+ if (dev->phy.type == B43_PHYTYPE_N) {
-+ if (have_5ghz_phy)
-+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy;
-+ } else {
-+ if (have_5ghz_phy)
-+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy;
-+ }
-+
-+ dev->phy.supports_2ghz = have_2ghz_phy;
-+ dev->phy.supports_5ghz = have_5ghz_phy;
-
- return 0;
- }
-@@ -3910,7 +4324,7 @@
- err = b43_validate_chipaccess(dev);
- if (err)
- goto err_powerdown;
-- err = b43_setup_modes(dev, have_2ghz_phy, have_5ghz_phy);
-+ err = b43_setup_bands(dev, have_2ghz_phy, have_5ghz_phy);
- if (err)
- goto err_powerdown;
-
-@@ -4040,7 +4454,7 @@
- hw->max_signal = 100;
- hw->max_rssi = -110;
- hw->max_noise = -110;
-- hw->queues = 1; /* FIXME: hardware has more queues */
-+ hw->queues = b43_modparam_qos ? 4 : 1;
- SET_IEEE80211_DEV(hw, dev->dev);
- if (is_valid_ether_addr(sprom->et1mac))
- SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
-@@ -4056,6 +4470,8 @@
- spin_lock_init(&wl->shm_lock);
- mutex_init(&wl->mutex);
- INIT_LIST_HEAD(&wl->devlist);
-+ INIT_WORK(&wl->qos_update_work, b43_qos_update_work);
-+ INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
-
- ssb_set_devtypedata(dev, wl);
- b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/main.h linux-2.6.25/drivers/net/wireless/b43/main.h
---- linux-2.6.25.old/drivers/net/wireless/b43/main.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/main.h 2008-04-19 13:54:59.000000000 +0200
-@@ -38,6 +38,10 @@
- /* Magic helper macro to pad structures. Ignore those above. It's magic. */
- #define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes))
-
-+
-+extern int b43_modparam_qos;
-+
-+
- /* Lightweight function to convert a frequency (in Mhz) to a channel number. */
- static inline u8 b43_freq_to_channel_5ghz(int freq)
- {
-@@ -95,16 +99,13 @@
- void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
- void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
-
--u32 b43_hf_read(struct b43_wldev *dev);
--void b43_hf_write(struct b43_wldev *dev, u32 value);
-+u64 b43_hf_read(struct b43_wldev *dev);
-+void b43_hf_write(struct b43_wldev *dev, u64 value);
-
- void b43_dummy_transmission(struct b43_wldev *dev);
-
- void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags);
-
--void b43_mac_suspend(struct b43_wldev *dev);
--void b43_mac_enable(struct b43_wldev *dev);
--
- void b43_controller_restart(struct b43_wldev *dev, const char *reason);
-
- #define B43_PS_ENABLED (1 << 0) /* Force enable hardware power saving */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/Makefile linux-2.6.25/drivers/net/wireless/b43/Makefile
---- linux-2.6.25.old/drivers/net/wireless/b43/Makefile 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/Makefile 2008-04-19 13:54:59.000000000 +0200
-@@ -1,13 +1,14 @@
- b43-y += main.o
- b43-y += tables.o
--b43-y += tables_nphy.o
-+b43-$(CONFIG_B43_NPHY) += tables_nphy.o
- b43-y += phy.o
--b43-y += nphy.o
-+b43-$(CONFIG_B43_NPHY) += nphy.o
- b43-y += sysfs.o
- b43-y += xmit.o
- b43-y += lo.o
- b43-y += wa.o
- b43-y += dma.o
-+b43-$(CONFIG_B43_PIO) += pio.o
- b43-$(CONFIG_B43_RFKILL) += rfkill.o
- b43-$(CONFIG_B43_LEDS) += leds.o
- b43-$(CONFIG_B43_PCMCIA) += pcmcia.o
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/nphy.c linux-2.6.25/drivers/net/wireless/b43/nphy.c
---- linux-2.6.25.old/drivers/net/wireless/b43/nphy.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/nphy.c 2008-04-19 13:54:59.000000000 +0200
-@@ -240,7 +240,6 @@
-
- b43_phy_set(dev, B43_NPHY_IQFLIP,
- B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
-- //FIXME the following condition is different in the specs.
- if (1 /* FIXME band is 2.4GHz */) {
- b43_phy_set(dev, B43_NPHY_CLASSCTL,
- B43_NPHY_CLASSCTL_CCKEN);
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/nphy.h linux-2.6.25/drivers/net/wireless/b43/nphy.h
---- linux-2.6.25.old/drivers/net/wireless/b43/nphy.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/nphy.h 2008-04-19 13:54:59.000000000 +0200
-@@ -919,6 +919,10 @@
-
- struct b43_wldev;
-
-+
-+#ifdef CONFIG_B43_NPHY
-+/* N-PHY support enabled */
-+
- int b43_phy_initn(struct b43_wldev *dev);
-
- void b43_nphy_radio_turn_on(struct b43_wldev *dev);
-@@ -929,4 +933,40 @@
- void b43_nphy_xmitpower(struct b43_wldev *dev);
- void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna);
-
-+
-+#else /* CONFIG_B43_NPHY */
-+/* N-PHY support disabled */
-+
-+
-+static inline
-+int b43_phy_initn(struct b43_wldev *dev)
-+{
-+ return -EOPNOTSUPP;
-+}
-+
-+static inline
-+void b43_nphy_radio_turn_on(struct b43_wldev *dev)
-+{
-+}
-+static inline
-+void b43_nphy_radio_turn_off(struct b43_wldev *dev)
-+{
-+}
-+
-+static inline
-+int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel)
-+{
-+ return -ENOSYS;
-+}
-+
-+static inline
-+void b43_nphy_xmitpower(struct b43_wldev *dev)
-+{
-+}
-+static inline
-+void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
-+{
-+}
-+
-+#endif /* CONFIG_B43_NPHY */
- #endif /* B43_NPHY_H_ */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/pcmcia.c linux-2.6.25/drivers/net/wireless/b43/pcmcia.c
---- linux-2.6.25.old/drivers/net/wireless/b43/pcmcia.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/pcmcia.c 2008-04-19 16:24:28.000000000 +0200
-@@ -43,14 +43,16 @@
- #ifdef CONFIG_PM
- static int b43_pcmcia_suspend(struct pcmcia_device *dev)
- {
-- //TODO
-- return 0;
-+ struct ssb_bus *ssb = dev->priv;
-+
-+ return ssb_bus_suspend(ssb);
- }
-
- static int b43_pcmcia_resume(struct pcmcia_device *dev)
- {
-- //TODO
-- return 0;
-+ struct ssb_bus *ssb = dev->priv;
-+
-+ return ssb_bus_resume(ssb);
- }
- #else /* CONFIG_PM */
- # define b43_pcmcia_suspend NULL
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/pio.c linux-2.6.25/drivers/net/wireless/b43/pio.c
---- linux-2.6.25.old/drivers/net/wireless/b43/pio.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.25/drivers/net/wireless/b43/pio.c 2008-04-19 13:54:59.000000000 +0200
-@@ -0,0 +1,842 @@
-+/*
-+
-+ Broadcom B43 wireless driver
-+
-+ PIO data transfer
-+
-+ Copyright (c) 2005-2008 Michael Buesch <mb@bu3sch.de>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; see the file COPYING. If not, write to
-+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
-+ Boston, MA 02110-1301, USA.
-+
-+*/
-+
-+#include "b43.h"
-+#include "pio.h"
-+#include "dma.h"
-+#include "main.h"
-+#include "xmit.h"
-+
-+#include <linux/delay.h>
-+
-+
-+static void b43_pio_rx_work(struct work_struct *work);
-+
-+
-+static u16 generate_cookie(struct b43_pio_txqueue *q,
-+ struct b43_pio_txpacket *pack)
-+{
-+ u16 cookie;
-+
-+ /* Use the upper 4 bits of the cookie as
-+ * PIO controller ID and store the packet index number
-+ * in the lower 12 bits.
-+ * Note that the cookie must never be 0, as this
-+ * is a special value used in RX path.
-+ * It can also not be 0xFFFF because that is special
-+ * for multicast frames.
-+ */
-+ cookie = (((u16)q->index + 1) << 12);
-+ cookie |= pack->index;
-+
-+ return cookie;
-+}
-+
-+static
-+struct b43_pio_txqueue * parse_cookie(struct b43_wldev *dev,
-+ u16 cookie,
-+ struct b43_pio_txpacket **pack)
-+{
-+ struct b43_pio *pio = &dev->pio;
-+ struct b43_pio_txqueue *q = NULL;
-+ unsigned int pack_index;
-+
-+ switch (cookie & 0xF000) {
-+ case 0x1000:
-+ q = pio->tx_queue_AC_BK;
-+ break;
-+ case 0x2000:
-+ q = pio->tx_queue_AC_BE;
-+ break;
-+ case 0x3000:
-+ q = pio->tx_queue_AC_VI;
-+ break;
-+ case 0x4000:
-+ q = pio->tx_queue_AC_VO;
-+ break;
-+ case 0x5000:
-+ q = pio->tx_queue_mcast;
-+ break;
-+ }
-+ if (B43_WARN_ON(!q))
-+ return NULL;
-+ pack_index = (cookie & 0x0FFF);
-+ if (B43_WARN_ON(pack_index >= ARRAY_SIZE(q->packets)))
-+ return NULL;
-+ *pack = &q->packets[pack_index];
-+
-+ return q;
-+}
-+
-+static u16 index_to_pioqueue_base(struct b43_wldev *dev,
-+ unsigned int index)
-+{
-+ static const u16 bases[] = {
-+ B43_MMIO_PIO_BASE0,
-+ B43_MMIO_PIO_BASE1,
-+ B43_MMIO_PIO_BASE2,
-+ B43_MMIO_PIO_BASE3,
-+ B43_MMIO_PIO_BASE4,
-+ B43_MMIO_PIO_BASE5,
-+ B43_MMIO_PIO_BASE6,
-+ B43_MMIO_PIO_BASE7,
-+ };
-+ static const u16 bases_rev11[] = {
-+ B43_MMIO_PIO11_BASE0,
-+ B43_MMIO_PIO11_BASE1,
-+ B43_MMIO_PIO11_BASE2,
-+ B43_MMIO_PIO11_BASE3,
-+ B43_MMIO_PIO11_BASE4,
-+ B43_MMIO_PIO11_BASE5,
-+ };
-+
-+ if (dev->dev->id.revision >= 11) {
-+ B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11));
-+ return bases_rev11[index];
-+ }
-+ B43_WARN_ON(index >= ARRAY_SIZE(bases));
-+ return bases[index];
-+}
-+
-+static u16 pio_txqueue_offset(struct b43_wldev *dev)
-+{
-+ if (dev->dev->id.revision >= 11)
-+ return 0x18;
-+ return 0;
-+}
-+
-+static u16 pio_rxqueue_offset(struct b43_wldev *dev)
-+{
-+ if (dev->dev->id.revision >= 11)
-+ return 0x38;
-+ return 8;
-+}
-+
-+static struct b43_pio_txqueue * b43_setup_pioqueue_tx(struct b43_wldev *dev,
-+ unsigned int index)
-+{
-+ struct b43_pio_txqueue *q;
-+ struct b43_pio_txpacket *p;
-+ unsigned int i;
-+
-+ q = kzalloc(sizeof(*q), GFP_KERNEL);
-+ if (!q)
-+ return NULL;
-+ spin_lock_init(&q->lock);
-+ q->dev = dev;
-+ q->rev = dev->dev->id.revision;
-+ q->mmio_base = index_to_pioqueue_base(dev, index) +
-+ pio_txqueue_offset(dev);
-+ q->index = index;
-+
-+ q->free_packet_slots = B43_PIO_MAX_NR_TXPACKETS;
-+ if (q->rev >= 8) {
-+ q->buffer_size = 1920; //FIXME this constant is wrong.
-+ } else {
-+ q->buffer_size = b43_piotx_read16(q, B43_PIO_TXQBUFSIZE);
-+ q->buffer_size -= 80;
-+ }
-+
-+ INIT_LIST_HEAD(&q->packets_list);
-+ for (i = 0; i < ARRAY_SIZE(q->packets); i++) {
-+ p = &(q->packets[i]);
-+ INIT_LIST_HEAD(&p->list);
-+ p->index = i;
-+ p->queue = q;
-+ list_add(&p->list, &q->packets_list);
-+ }
-+
-+ return q;
-+}
-+
-+static struct b43_pio_rxqueue * b43_setup_pioqueue_rx(struct b43_wldev *dev,
-+ unsigned int index)
-+{
-+ struct b43_pio_rxqueue *q;
-+
-+ q = kzalloc(sizeof(*q), GFP_KERNEL);
-+ if (!q)
-+ return NULL;
-+ spin_lock_init(&q->lock);
-+ q->dev = dev;
-+ q->rev = dev->dev->id.revision;
-+ q->mmio_base = index_to_pioqueue_base(dev, index) +
-+ pio_rxqueue_offset(dev);
-+ INIT_WORK(&q->rx_work, b43_pio_rx_work);
-+
-+ /* Enable Direct FIFO RX (PIO) on the engine. */
-+ b43_dma_direct_fifo_rx(dev, index, 1);
-+
-+ return q;
-+}
-+
-+static void b43_pio_cancel_tx_packets(struct b43_pio_txqueue *q)
-+{
-+ struct b43_pio_txpacket *pack;
-+ unsigned int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(q->packets); i++) {
-+ pack = &(q->packets[i]);
-+ if (pack->skb) {
-+ dev_kfree_skb_any(pack->skb);
-+ pack->skb = NULL;
-+ }
-+ }
-+}
-+
-+static void b43_destroy_pioqueue_tx(struct b43_pio_txqueue *q,
-+ const char *name)
-+{
-+ if (!q)
-+ return;
-+ b43_pio_cancel_tx_packets(q);
-+ kfree(q);
-+}
-+
-+static void b43_destroy_pioqueue_rx(struct b43_pio_rxqueue *q,
-+ const char *name)
-+{
-+ if (!q)
-+ return;
-+ kfree(q);
-+}
-+
-+#define destroy_queue_tx(pio, queue) do { \
-+ b43_destroy_pioqueue_tx((pio)->queue, __stringify(queue)); \
-+ (pio)->queue = NULL; \
-+ } while (0)
-+
-+#define destroy_queue_rx(pio, queue) do { \
-+ b43_destroy_pioqueue_rx((pio)->queue, __stringify(queue)); \
-+ (pio)->queue = NULL; \
-+ } while (0)
-+
-+void b43_pio_free(struct b43_wldev *dev)
-+{
-+ struct b43_pio *pio;
-+
-+ if (!b43_using_pio_transfers(dev))
-+ return;
-+ pio = &dev->pio;
-+
-+ destroy_queue_rx(pio, rx_queue);
-+ destroy_queue_tx(pio, tx_queue_mcast);
-+ destroy_queue_tx(pio, tx_queue_AC_VO);
-+ destroy_queue_tx(pio, tx_queue_AC_VI);
-+ destroy_queue_tx(pio, tx_queue_AC_BE);
-+ destroy_queue_tx(pio, tx_queue_AC_BK);
-+}
-+
-+void b43_pio_stop(struct b43_wldev *dev)
-+{
-+ if (!b43_using_pio_transfers(dev))
-+ return;
-+ cancel_work_sync(&dev->pio.rx_queue->rx_work);
-+}
-+
-+int b43_pio_init(struct b43_wldev *dev)
-+{
-+ struct b43_pio *pio = &dev->pio;
-+ int err = -ENOMEM;
-+
-+ b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
-+ & ~B43_MACCTL_BE);
-+ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_RXPADOFF, 0);
-+
-+ pio->tx_queue_AC_BK = b43_setup_pioqueue_tx(dev, 0);
-+ if (!pio->tx_queue_AC_BK)
-+ goto out;
-+
-+ pio->tx_queue_AC_BE = b43_setup_pioqueue_tx(dev, 1);
-+ if (!pio->tx_queue_AC_BE)
-+ goto err_destroy_bk;
-+
-+ pio->tx_queue_AC_VI = b43_setup_pioqueue_tx(dev, 2);
-+ if (!pio->tx_queue_AC_VI)
-+ goto err_destroy_be;
-+
-+ pio->tx_queue_AC_VO = b43_setup_pioqueue_tx(dev, 3);
-+ if (!pio->tx_queue_AC_VO)
-+ goto err_destroy_vi;
-+
-+ pio->tx_queue_mcast = b43_setup_pioqueue_tx(dev, 4);
-+ if (!pio->tx_queue_mcast)
-+ goto err_destroy_vo;
-+
-+ pio->rx_queue = b43_setup_pioqueue_rx(dev, 0);
-+ if (!pio->rx_queue)
-+ goto err_destroy_mcast;
-+
-+ b43dbg(dev->wl, "PIO initialized\n");
-+ err = 0;
-+out:
-+ return err;
-+
-+err_destroy_mcast:
-+ destroy_queue_tx(pio, tx_queue_mcast);
-+err_destroy_vo:
-+ destroy_queue_tx(pio, tx_queue_AC_VO);
-+err_destroy_vi:
-+ destroy_queue_tx(pio, tx_queue_AC_VI);
-+err_destroy_be:
-+ destroy_queue_tx(pio, tx_queue_AC_BE);
-+err_destroy_bk:
-+ destroy_queue_tx(pio, tx_queue_AC_BK);
-+ return err;
-+}
-+
-+/* Static mapping of mac80211's queues (priorities) to b43 PIO queues. */
-+static struct b43_pio_txqueue * select_queue_by_priority(struct b43_wldev *dev,
-+ u8 queue_prio)
-+{
-+ struct b43_pio_txqueue *q;
-+
-+ if (b43_modparam_qos) {
-+ /* 0 = highest priority */
-+ switch (queue_prio) {
-+ default:
-+ B43_WARN_ON(1);
-+ /* fallthrough */
-+ case 0:
-+ q = dev->pio.tx_queue_AC_VO;
-+ break;
-+ case 1:
-+ q = dev->pio.tx_queue_AC_VI;
-+ break;
-+ case 2:
-+ q = dev->pio.tx_queue_AC_BE;
-+ break;
-+ case 3:
-+ q = dev->pio.tx_queue_AC_BK;
-+ break;
-+ }
-+ } else
-+ q = dev->pio.tx_queue_AC_BE;
-+
-+ return q;
-+}
-+
-+static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
-+ u16 ctl,
-+ const void *_data,
-+ unsigned int data_len)
-+{
-+ struct b43_wldev *dev = q->dev;
-+ const u8 *data = _data;
-+
-+ ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
-+ b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
-+
-+ ssb_block_write(dev->dev, data, (data_len & ~1),
-+ q->mmio_base + B43_PIO_TXDATA,
-+ sizeof(u16));
-+ if (data_len & 1) {
-+ /* Write the last byte. */
-+ ctl &= ~B43_PIO_TXCTL_WRITEHI;
-+ b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
-+ b43_piotx_write16(q, B43_PIO_TXDATA, data[data_len - 1]);
-+ }
-+
-+ return ctl;
-+}
-+
-+static void pio_tx_frame_2byte_queue(struct b43_pio_txpacket *pack,
-+ const u8 *hdr, unsigned int hdrlen)
-+{
-+ struct b43_pio_txqueue *q = pack->queue;
-+ const char *frame = pack->skb->data;
-+ unsigned int frame_len = pack->skb->len;
-+ u16 ctl;
-+
-+ ctl = b43_piotx_read16(q, B43_PIO_TXCTL);
-+ ctl |= B43_PIO_TXCTL_FREADY;
-+ ctl &= ~B43_PIO_TXCTL_EOF;
-+
-+ /* Transfer the header data. */
-+ ctl = tx_write_2byte_queue(q, ctl, hdr, hdrlen);
-+ /* Transfer the frame data. */
-+ ctl = tx_write_2byte_queue(q, ctl, frame, frame_len);
-+
-+ ctl |= B43_PIO_TXCTL_EOF;
-+ b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
-+}
-+
-+static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
-+ u32 ctl,
-+ const void *_data,
-+ unsigned int data_len)
-+{
-+ struct b43_wldev *dev = q->dev;
-+ const u8 *data = _data;
-+
-+ ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 |
-+ B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31;
-+ b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
-+
-+ ssb_block_write(dev->dev, data, (data_len & ~3),
-+ q->mmio_base + B43_PIO8_TXDATA,
-+ sizeof(u32));
-+ if (data_len & 3) {
-+ u32 value = 0;
-+
-+ /* Write the last few bytes. */
-+ ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
-+ B43_PIO8_TXCTL_24_31);
-+ data = &(data[data_len - 1]);
-+ switch (data_len & 3) {
-+ case 3:
-+ ctl |= B43_PIO8_TXCTL_16_23;
-+ value |= (u32)(*data) << 16;
-+ data--;
-+ case 2:
-+ ctl |= B43_PIO8_TXCTL_8_15;
-+ value |= (u32)(*data) << 8;
-+ data--;
-+ case 1:
-+ value |= (u32)(*data);
-+ }
-+ b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
-+ b43_piotx_write32(q, B43_PIO8_TXDATA, value);
-+ }
-+
-+ return ctl;
-+}
-+
-+static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
-+ const u8 *hdr, unsigned int hdrlen)
-+{
-+ struct b43_pio_txqueue *q = pack->queue;
-+ const char *frame = pack->skb->data;
-+ unsigned int frame_len = pack->skb->len;
-+ u32 ctl;
-+
-+ ctl = b43_piotx_read32(q, B43_PIO8_TXCTL);
-+ ctl |= B43_PIO8_TXCTL_FREADY;
-+ ctl &= ~B43_PIO8_TXCTL_EOF;
-+
-+ /* Transfer the header data. */
-+ ctl = tx_write_4byte_queue(q, ctl, hdr, hdrlen);
-+ /* Transfer the frame data. */
-+ ctl = tx_write_4byte_queue(q, ctl, frame, frame_len);
-+
-+ ctl |= B43_PIO8_TXCTL_EOF;
-+ b43_piotx_write32(q, B43_PIO_TXCTL, ctl);
-+}
-+
-+static int pio_tx_frame(struct b43_pio_txqueue *q,
-+ struct sk_buff *skb,
-+ struct ieee80211_tx_control *ctl)
-+{
-+ struct b43_pio_txpacket *pack;
-+ struct b43_txhdr txhdr;
-+ u16 cookie;
-+ int err;
-+ unsigned int hdrlen;
-+
-+ B43_WARN_ON(list_empty(&q->packets_list));
-+ pack = list_entry(q->packets_list.next,
-+ struct b43_pio_txpacket, list);
-+ memset(&pack->txstat, 0, sizeof(pack->txstat));
-+ memcpy(&pack->txstat.control, ctl, sizeof(*ctl));
-+
-+ cookie = generate_cookie(q, pack);
-+ hdrlen = b43_txhdr_size(q->dev);
-+ err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb->data,
-+ skb->len, ctl, cookie);
-+ if (err)
-+ return err;
-+
-+ if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
-+ /* Tell the firmware about the cookie of the last
-+ * mcast frame, so it can clear the more-data bit in it. */
-+ b43_shm_write16(q->dev, B43_SHM_SHARED,
-+ B43_SHM_SH_MCASTCOOKIE, cookie);
-+ }
-+
-+ pack->skb = skb;
-+ if (q->rev >= 8)
-+ pio_tx_frame_4byte_queue(pack, (const u8 *)&txhdr, hdrlen);
-+ else
-+ pio_tx_frame_2byte_queue(pack, (const u8 *)&txhdr, hdrlen);
-+
-+ /* Remove it from the list of available packet slots.
-+ * It will be put back when we receive the status report. */
-+ list_del(&pack->list);
-+
-+ /* Update the queue statistics. */
-+ q->buffer_used += roundup(skb->len + hdrlen, 4);
-+ q->free_packet_slots -= 1;
-+
-+ return 0;
-+}
-+
-+int b43_pio_tx(struct b43_wldev *dev,
-+ struct sk_buff *skb, struct ieee80211_tx_control *ctl)
-+{
-+ struct b43_pio_txqueue *q;
-+ struct ieee80211_hdr *hdr;
-+ unsigned long flags;
-+ unsigned int hdrlen, total_len;
-+ int err = 0;
-+
-+ hdr = (struct ieee80211_hdr *)skb->data;
-+ if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
-+ /* The multicast queue will be sent after the DTIM. */
-+ q = dev->pio.tx_queue_mcast;
-+ /* Set the frame More-Data bit. Ucode will clear it
-+ * for us on the last frame. */
-+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-+ } else {
-+ /* Decide by priority where to put this frame. */
-+ q = select_queue_by_priority(dev, ctl->queue);
-+ }
-+
-+ spin_lock_irqsave(&q->lock, flags);
-+
-+ hdrlen = b43_txhdr_size(dev);
-+ total_len = roundup(skb->len + hdrlen, 4);
-+
-+ if (unlikely(total_len > q->buffer_size)) {
-+ err = -ENOBUFS;
-+ b43dbg(dev->wl, "PIO: TX packet longer than queue.\n");
-+ goto out_unlock;
-+ }
-+ if (unlikely(q->free_packet_slots == 0)) {
-+ err = -ENOBUFS;
-+ b43warn(dev->wl, "PIO: TX packet overflow.\n");
-+ goto out_unlock;
-+ }
-+ B43_WARN_ON(q->buffer_used > q->buffer_size);
-+
-+ if (total_len > (q->buffer_size - q->buffer_used)) {
-+ /* Not enough memory on the queue. */
-+ err = -EBUSY;
-+ ieee80211_stop_queue(dev->wl->hw, ctl->queue);
-+ q->stopped = 1;
-+ goto out_unlock;
-+ }
-+
-+ /* Assign the queue number to the ring (if not already done before)
-+ * so TX status handling can use it. The mac80211-queue to b43-queue
-+ * mapping is static, so we don't need to store it per frame. */
-+ q->queue_prio = ctl->queue;
-+
-+ err = pio_tx_frame(q, skb, ctl);
-+ if (unlikely(err == -ENOKEY)) {
-+ /* Drop this packet, as we don't have the encryption key
-+ * anymore and must not transmit it unencrypted. */
-+ dev_kfree_skb_any(skb);
-+ err = 0;
-+ goto out_unlock;
-+ }
-+ if (unlikely(err)) {
-+ b43err(dev->wl, "PIO transmission failure\n");
-+ goto out_unlock;
-+ }
-+ q->nr_tx_packets++;
-+
-+ B43_WARN_ON(q->buffer_used > q->buffer_size);
-+ if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
-+ (q->free_packet_slots == 0)) {
-+ /* The queue is full. */
-+ ieee80211_stop_queue(dev->wl->hw, ctl->queue);
-+ q->stopped = 1;
-+ }
-+
-+out_unlock:
-+ spin_unlock_irqrestore(&q->lock, flags);
-+
-+ return err;
-+}
-+
-+/* Called with IRQs disabled. */
-+void b43_pio_handle_txstatus(struct b43_wldev *dev,
-+ const struct b43_txstatus *status)
-+{
-+ struct b43_pio_txqueue *q;
-+ struct b43_pio_txpacket *pack = NULL;
-+ unsigned int total_len;
-+
-+ q = parse_cookie(dev, status->cookie, &pack);
-+ if (unlikely(!q))
-+ return;
-+ B43_WARN_ON(!pack);
-+
-+ spin_lock(&q->lock); /* IRQs are already disabled. */
-+
-+ b43_fill_txstatus_report(&(pack->txstat), status);
-+
-+ total_len = pack->skb->len + b43_txhdr_size(dev);
-+ total_len = roundup(total_len, 4);
-+ q->buffer_used -= total_len;
-+ q->free_packet_slots += 1;
-+
-+ ieee80211_tx_status_irqsafe(dev->wl->hw, pack->skb,
-+ &(pack->txstat));
-+ pack->skb = NULL;
-+ list_add(&pack->list, &q->packets_list);
-+
-+ if (q->stopped) {
-+ ieee80211_wake_queue(dev->wl->hw, q->queue_prio);
-+ q->stopped = 0;
-+ }
-+
-+ spin_unlock(&q->lock);
-+}
-+
-+void b43_pio_get_tx_stats(struct b43_wldev *dev,
-+ struct ieee80211_tx_queue_stats *stats)
-+{
-+ const int nr_queues = dev->wl->hw->queues;
-+ struct b43_pio_txqueue *q;
-+ struct ieee80211_tx_queue_stats_data *data;
-+ unsigned long flags;
-+ int i;
-+
-+ for (i = 0; i < nr_queues; i++) {
-+ data = &(stats->data[i]);
-+ q = select_queue_by_priority(dev, i);
-+
-+ spin_lock_irqsave(&q->lock, flags);
-+ data->len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots;
-+ data->limit = B43_PIO_MAX_NR_TXPACKETS;
-+ data->count = q->nr_tx_packets;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+ }
-+}
-+
-+/* Returns whether we should fetch another frame. */
-+static bool pio_rx_frame(struct b43_pio_rxqueue *q)
-+{
-+ struct b43_wldev *dev = q->dev;
-+ struct b43_rxhdr_fw4 rxhdr;
-+ u16 len;
-+ u32 macstat;
-+ unsigned int i, padding;
-+ struct sk_buff *skb;
-+ const char *err_msg = NULL;
-+
-+ memset(&rxhdr, 0, sizeof(rxhdr));
-+
-+ /* Check if we have data and wait for it to get ready. */
-+ if (q->rev >= 8) {
-+ u32 ctl;
-+
-+ ctl = b43_piorx_read32(q, B43_PIO8_RXCTL);
-+ if (!(ctl & B43_PIO8_RXCTL_FRAMERDY))
-+ return 0;
-+ b43_piorx_write32(q, B43_PIO8_RXCTL,
-+ B43_PIO8_RXCTL_FRAMERDY);
-+ for (i = 0; i < 10; i++) {
-+ ctl = b43_piorx_read32(q, B43_PIO8_RXCTL);
-+ if (ctl & B43_PIO8_RXCTL_DATARDY)
-+ goto data_ready;
-+ udelay(10);
-+ }
-+ } else {
-+ u16 ctl;
-+
-+ ctl = b43_piorx_read16(q, B43_PIO_RXCTL);
-+ if (!(ctl & B43_PIO_RXCTL_FRAMERDY))
-+ return 0;
-+ b43_piorx_write16(q, B43_PIO_RXCTL,
-+ B43_PIO_RXCTL_FRAMERDY);
-+ for (i = 0; i < 10; i++) {
-+ ctl = b43_piorx_read16(q, B43_PIO_RXCTL);
-+ if (ctl & B43_PIO_RXCTL_DATARDY)
-+ goto data_ready;
-+ udelay(10);
-+ }
-+ }
-+ b43dbg(q->dev->wl, "PIO RX timed out\n");
-+ return 1;
-+data_ready:
-+
-+ /* Get the preamble (RX header) */
-+ if (q->rev >= 8) {
-+ ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr),
-+ q->mmio_base + B43_PIO8_RXDATA,
-+ sizeof(u32));
-+ } else {
-+ ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr),
-+ q->mmio_base + B43_PIO_RXDATA,
-+ sizeof(u16));
-+ }
-+ /* Sanity checks. */
-+ len = le16_to_cpu(rxhdr.frame_len);
-+ if (unlikely(len > 0x700)) {
-+ err_msg = "len > 0x700";
-+ goto rx_error;
-+ }
-+ if (unlikely(len == 0)) {
-+ err_msg = "len == 0";
-+ goto rx_error;
-+ }
-+
-+ macstat = le32_to_cpu(rxhdr.mac_status);
-+ if (macstat & B43_RX_MAC_FCSERR) {
-+ if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
-+ /* Drop frames with failed FCS. */
-+ err_msg = "Frame FCS error";
-+ goto rx_error;
-+ }
-+ }
-+
-+ /* We always pad 2 bytes, as that's what upstream code expects
-+ * due to the RX-header being 30 bytes. In case the frame is
-+ * unaligned, we pad another 2 bytes. */
-+ padding = (macstat & B43_RX_MAC_PADDING) ? 2 : 0;
-+ skb = dev_alloc_skb(len + padding + 2);
-+ if (unlikely(!skb)) {
-+ err_msg = "Out of memory";
-+ goto rx_error;
-+ }
-+ skb_reserve(skb, 2);
-+ skb_put(skb, len + padding);
-+ if (q->rev >= 8) {
-+ ssb_block_read(dev->dev, skb->data + padding, (len & ~3),
-+ q->mmio_base + B43_PIO8_RXDATA,
-+ sizeof(u32));
-+ if (len & 3) {
-+ u32 value;
-+ char *data;
-+
-+ /* Read the last few bytes. */
-+ value = b43_piorx_read32(q, B43_PIO8_RXDATA);
-+ data = &(skb->data[len + padding - 1]);
-+ switch (len & 3) {
-+ case 3:
-+ *data = (value >> 16);
-+ data--;
-+ case 2:
-+ *data = (value >> 8);
-+ data--;
-+ case 1:
-+ *data = value;
-+ }
-+ }
-+ } else {
-+ ssb_block_read(dev->dev, skb->data + padding, (len & ~1),
-+ q->mmio_base + B43_PIO_RXDATA,
-+ sizeof(u16));
-+ if (len & 1) {
-+ u16 value;
-+
-+ /* Read the last byte. */
-+ value = b43_piorx_read16(q, B43_PIO_RXDATA);
-+ skb->data[len + padding - 1] = value;
-+ }
-+ }
-+
-+ b43_rx(q->dev, skb, &rxhdr);
-+
-+ return 1;
-+
-+rx_error:
-+ if (err_msg)
-+ b43dbg(q->dev->wl, "PIO RX error: %s\n", err_msg);
-+ b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY);
-+ return 1;
-+}
-+
-+/* RX workqueue. We can sleep, yay! */
-+static void b43_pio_rx_work(struct work_struct *work)
-+{
-+ struct b43_pio_rxqueue *q = container_of(work, struct b43_pio_rxqueue,
-+ rx_work);
-+ unsigned int budget = 50;
-+ bool stop;
-+
-+ do {
-+ spin_lock_irq(&q->lock);
-+ stop = (pio_rx_frame(q) == 0);
-+ spin_unlock_irq(&q->lock);
-+ cond_resched();
-+ if (stop)
-+ break;
-+ } while (--budget);
-+}
-+
-+/* Called with IRQs disabled. */
-+void b43_pio_rx(struct b43_pio_rxqueue *q)
-+{
-+ /* Due to latency issues we must run the RX path in
-+ * a workqueue to be able to schedule between packets. */
-+ queue_work(q->dev->wl->hw->workqueue, &q->rx_work);
-+}
-+
-+static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&q->lock, flags);
-+ if (q->rev >= 8) {
-+ b43_piotx_write32(q, B43_PIO8_TXCTL,
-+ b43_piotx_read32(q, B43_PIO8_TXCTL)
-+ | B43_PIO8_TXCTL_SUSPREQ);
-+ } else {
-+ b43_piotx_write16(q, B43_PIO_TXCTL,
-+ b43_piotx_read16(q, B43_PIO_TXCTL)
-+ | B43_PIO_TXCTL_SUSPREQ);
-+ }
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+static void b43_pio_tx_resume_queue(struct b43_pio_txqueue *q)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&q->lock, flags);
-+ if (q->rev >= 8) {
-+ b43_piotx_write32(q, B43_PIO8_TXCTL,
-+ b43_piotx_read32(q, B43_PIO8_TXCTL)
-+ & ~B43_PIO8_TXCTL_SUSPREQ);
-+ } else {
-+ b43_piotx_write16(q, B43_PIO_TXCTL,
-+ b43_piotx_read16(q, B43_PIO_TXCTL)
-+ & ~B43_PIO_TXCTL_SUSPREQ);
-+ }
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+void b43_pio_tx_suspend(struct b43_wldev *dev)
-+{
-+ b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
-+ b43_pio_tx_suspend_queue(dev->pio.tx_queue_AC_BK);
-+ b43_pio_tx_suspend_queue(dev->pio.tx_queue_AC_BE);
-+ b43_pio_tx_suspend_queue(dev->pio.tx_queue_AC_VI);
-+ b43_pio_tx_suspend_queue(dev->pio.tx_queue_AC_VO);
-+ b43_pio_tx_suspend_queue(dev->pio.tx_queue_mcast);
-+}
-+
-+void b43_pio_tx_resume(struct b43_wldev *dev)
-+{
-+ b43_pio_tx_resume_queue(dev->pio.tx_queue_mcast);
-+ b43_pio_tx_resume_queue(dev->pio.tx_queue_AC_VO);
-+ b43_pio_tx_resume_queue(dev->pio.tx_queue_AC_VI);
-+ b43_pio_tx_resume_queue(dev->pio.tx_queue_AC_BE);
-+ b43_pio_tx_resume_queue(dev->pio.tx_queue_AC_BK);
-+ b43_power_saving_ctl_bits(dev, 0);
-+}
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/pio.h linux-2.6.25/drivers/net/wireless/b43/pio.h
---- linux-2.6.25.old/drivers/net/wireless/b43/pio.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.25/drivers/net/wireless/b43/pio.h 2008-04-19 13:54:59.000000000 +0200
-@@ -0,0 +1,220 @@
-+#ifndef B43_PIO_H_
-+#define B43_PIO_H_
-+
-+#include "b43.h"
-+
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/list.h>
-+#include <linux/skbuff.h>
-+
-+
-+/*** Registers for PIO queues up to revision 7. ***/
-+/* TX queue. */
-+#define B43_PIO_TXCTL 0x00
-+#define B43_PIO_TXCTL_WRITELO 0x0001
-+#define B43_PIO_TXCTL_WRITEHI 0x0002
-+#define B43_PIO_TXCTL_EOF 0x0004
-+#define B43_PIO_TXCTL_FREADY 0x0008
-+#define B43_PIO_TXCTL_FLUSHREQ 0x0020
-+#define B43_PIO_TXCTL_FLUSHPEND 0x0040
-+#define B43_PIO_TXCTL_SUSPREQ 0x0080
-+#define B43_PIO_TXCTL_QSUSP 0x0100
-+#define B43_PIO_TXCTL_COMMCNT 0xFC00
-+#define B43_PIO_TXCTL_COMMCNT_SHIFT 10
-+#define B43_PIO_TXDATA 0x02
-+#define B43_PIO_TXQBUFSIZE 0x04
-+/* RX queue. */
-+#define B43_PIO_RXCTL 0x00
-+#define B43_PIO_RXCTL_FRAMERDY 0x0001
-+#define B43_PIO_RXCTL_DATARDY 0x0002
-+#define B43_PIO_RXDATA 0x02
-+
-+/*** Registers for PIO queues revision 8 and later. ***/
-+/* TX queue */
-+#define B43_PIO8_TXCTL 0x00
-+#define B43_PIO8_TXCTL_0_7 0x00000001
-+#define B43_PIO8_TXCTL_8_15 0x00000002
-+#define B43_PIO8_TXCTL_16_23 0x00000004
-+#define B43_PIO8_TXCTL_24_31 0x00000008
-+#define B43_PIO8_TXCTL_EOF 0x00000010
-+#define B43_PIO8_TXCTL_FREADY 0x00000080
-+#define B43_PIO8_TXCTL_SUSPREQ 0x00000100
-+#define B43_PIO8_TXCTL_QSUSP 0x00000200
-+#define B43_PIO8_TXCTL_FLUSHREQ 0x00000400
-+#define B43_PIO8_TXCTL_FLUSHPEND 0x00000800
-+#define B43_PIO8_TXDATA 0x04
-+/* RX queue */
-+#define B43_PIO8_RXCTL 0x00
-+#define B43_PIO8_RXCTL_FRAMERDY 0x00000001
-+#define B43_PIO8_RXCTL_DATARDY 0x00000002
-+#define B43_PIO8_RXDATA 0x04
-+
-+
-+/* The maximum number of TX-packets the HW can handle. */
-+#define B43_PIO_MAX_NR_TXPACKETS 32
-+
-+
-+#ifdef CONFIG_B43_PIO
-+
-+struct b43_pio_txpacket {
-+ /* Pointer to the TX queue we belong to. */
-+ struct b43_pio_txqueue *queue;
-+ /* The TX data packet. */
-+ struct sk_buff *skb;
-+ /* The status meta data. */
-+ struct ieee80211_tx_status txstat;
-+ /* Index in the (struct b43_pio_txqueue)->packets array. */
-+ u8 index;
-+
-+ struct list_head list;
-+};
-+
-+struct b43_pio_txqueue {
-+ struct b43_wldev *dev;
-+ spinlock_t lock;
-+ u16 mmio_base;
-+
-+ /* The device queue buffer size in bytes. */
-+ u16 buffer_size;
-+ /* The number of used bytes in the device queue buffer. */
-+ u16 buffer_used;
-+ /* The number of packets that can still get queued.
-+ * This is decremented on queueing a packet and incremented
-+ * after receiving the transmit status. */
-+ u16 free_packet_slots;
-+
-+ /* True, if the mac80211 queue was stopped due to overflow at TX. */
-+ bool stopped;
-+ /* Our b43 queue index number */
-+ u8 index;
-+ /* The mac80211 QoS queue priority. */
-+ u8 queue_prio;
-+
-+ /* Buffer for TX packet meta data. */
-+ struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS];
-+ struct list_head packets_list;
-+
-+ /* Total number of transmitted packets. */
-+ unsigned int nr_tx_packets;
-+
-+ /* Shortcut to the 802.11 core revision. This is to
-+ * avoid horrible pointer dereferencing in the fastpaths. */
-+ u8 rev;
-+};
-+
-+struct b43_pio_rxqueue {
-+ struct b43_wldev *dev;
-+ spinlock_t lock;
-+ u16 mmio_base;
-+
-+ /* Work to reduce latency issues on RX. */
-+ struct work_struct rx_work;
-+
-+ /* Shortcut to the 802.11 core revision. This is to
-+ * avoid horrible pointer dereferencing in the fastpaths. */
-+ u8 rev;
-+};
-+
-+
-+static inline u16 b43_piotx_read16(struct b43_pio_txqueue *q, u16 offset)
-+{
-+ return b43_read16(q->dev, q->mmio_base + offset);
-+}
-+
-+static inline u32 b43_piotx_read32(struct b43_pio_txqueue *q, u16 offset)
-+{
-+ return b43_read32(q->dev, q->mmio_base + offset);
-+}
-+
-+static inline void b43_piotx_write16(struct b43_pio_txqueue *q,
-+ u16 offset, u16 value)
-+{
-+ b43_write16(q->dev, q->mmio_base + offset, value);
-+}
-+
-+static inline void b43_piotx_write32(struct b43_pio_txqueue *q,
-+ u16 offset, u32 value)
-+{
-+ b43_write32(q->dev, q->mmio_base + offset, value);
-+}
-+
-+
-+static inline u16 b43_piorx_read16(struct b43_pio_rxqueue *q, u16 offset)
-+{
-+ return b43_read16(q->dev, q->mmio_base + offset);
-+}
-+
-+static inline u32 b43_piorx_read32(struct b43_pio_rxqueue *q, u16 offset)
-+{
-+ return b43_read32(q->dev, q->mmio_base + offset);
-+}
-+
-+static inline void b43_piorx_write16(struct b43_pio_rxqueue *q,
-+ u16 offset, u16 value)
-+{
-+ b43_write16(q->dev, q->mmio_base + offset, value);
-+}
-+
-+static inline void b43_piorx_write32(struct b43_pio_rxqueue *q,
-+ u16 offset, u32 value)
-+{
-+ b43_write32(q->dev, q->mmio_base + offset, value);
-+}
-+
-+
-+int b43_pio_init(struct b43_wldev *dev);
-+void b43_pio_stop(struct b43_wldev *dev);
-+void b43_pio_free(struct b43_wldev *dev);
-+
-+int b43_pio_tx(struct b43_wldev *dev,
-+ struct sk_buff *skb, struct ieee80211_tx_control *ctl);
-+void b43_pio_handle_txstatus(struct b43_wldev *dev,
-+ const struct b43_txstatus *status);
-+void b43_pio_get_tx_stats(struct b43_wldev *dev,
-+ struct ieee80211_tx_queue_stats *stats);
-+void b43_pio_rx(struct b43_pio_rxqueue *q);
-+
-+void b43_pio_tx_suspend(struct b43_wldev *dev);
-+void b43_pio_tx_resume(struct b43_wldev *dev);
-+
-+
-+#else /* CONFIG_B43_PIO */
-+
-+
-+static inline int b43_pio_init(struct b43_wldev *dev)
-+{
-+ return 0;
-+}
-+static inline void b43_pio_free(struct b43_wldev *dev)
-+{
-+}
-+static inline void b43_pio_stop(struct b43_wldev *dev)
-+{
-+}
-+static inline int b43_pio_tx(struct b43_wldev *dev,
-+ struct sk_buff *skb,
-+ struct ieee80211_tx_control *ctl)
-+{
-+ return 0;
-+}
-+static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
-+ const struct b43_txstatus *status)
-+{
-+}
-+static inline void b43_pio_get_tx_stats(struct b43_wldev *dev,
-+ struct ieee80211_tx_queue_stats *stats)
-+{
-+}
-+static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
-+{
-+}
-+static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
-+{
-+}
-+static inline void b43_pio_tx_resume(struct b43_wldev *dev)
-+{
-+}
-+
-+#endif /* CONFIG_B43_PIO */
-+#endif /* B43_PIO_H_ */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/sysfs.c linux-2.6.25/drivers/net/wireless/b43/sysfs.c
---- linux-2.6.25.old/drivers/net/wireless/b43/sysfs.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/sysfs.c 2008-04-19 13:54:59.000000000 +0200
-@@ -47,29 +47,6 @@
- return ret;
- }
-
--static int get_boolean(const char *buf, size_t count)
--{
-- if (count != 0) {
-- if (buf[0] == '1')
-- return 1;
-- if (buf[0] == '0')
-- return 0;
-- if (count >= 4 && memcmp(buf, "true", 4) == 0)
-- return 1;
-- if (count >= 5 && memcmp(buf, "false", 5) == 0)
-- return 0;
-- if (count >= 3 && memcmp(buf, "yes", 3) == 0)
-- return 1;
-- if (count >= 2 && memcmp(buf, "no", 2) == 0)
-- return 0;
-- if (count >= 2 && memcmp(buf, "on", 2) == 0)
-- return 1;
-- if (count >= 3 && memcmp(buf, "off", 3) == 0)
-- return 0;
-- }
-- return -EINVAL;
--}
--
- static ssize_t b43_attr_interfmode_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-@@ -155,82 +132,18 @@
- static DEVICE_ATTR(interference, 0644,
- b43_attr_interfmode_show, b43_attr_interfmode_store);
-
--static ssize_t b43_attr_preamble_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
--{
-- struct b43_wldev *wldev = dev_to_b43_wldev(dev);
-- ssize_t count;
--
-- if (!capable(CAP_NET_ADMIN))
-- return -EPERM;
--
-- mutex_lock(&wldev->wl->mutex);
--
-- if (wldev->short_preamble)
-- count =
-- snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
-- else
-- count =
-- snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
--
-- mutex_unlock(&wldev->wl->mutex);
--
-- return count;
--}
--
--static ssize_t b43_attr_preamble_store(struct device *dev,
-- struct device_attribute *attr,
-- const char *buf, size_t count)
--{
-- struct b43_wldev *wldev = dev_to_b43_wldev(dev);
-- unsigned long flags;
-- int value;
--
-- if (!capable(CAP_NET_ADMIN))
-- return -EPERM;
--
-- value = get_boolean(buf, count);
-- if (value < 0)
-- return value;
-- mutex_lock(&wldev->wl->mutex);
-- spin_lock_irqsave(&wldev->wl->irq_lock, flags);
--
-- wldev->short_preamble = !!value;
--
-- spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
-- mutex_unlock(&wldev->wl->mutex);
--
-- return count;
--}
--
--static DEVICE_ATTR(shortpreamble, 0644,
-- b43_attr_preamble_show, b43_attr_preamble_store);
--
- int b43_sysfs_register(struct b43_wldev *wldev)
- {
- struct device *dev = wldev->dev->dev;
-- int err;
-
- B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
-
-- err = device_create_file(dev, &dev_attr_interference);
-- if (err)
-- goto out;
-- err = device_create_file(dev, &dev_attr_shortpreamble);
-- if (err)
-- goto err_remove_interfmode;
--
-- out:
-- return err;
-- err_remove_interfmode:
-- device_remove_file(dev, &dev_attr_interference);
-- goto out;
-+ return device_create_file(dev, &dev_attr_interference);
- }
-
- void b43_sysfs_unregister(struct b43_wldev *wldev)
- {
- struct device *dev = wldev->dev->dev;
-
-- device_remove_file(dev, &dev_attr_shortpreamble);
- device_remove_file(dev, &dev_attr_interference);
- }
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/wa.c linux-2.6.25/drivers/net/wireless/b43/wa.c
---- linux-2.6.25.old/drivers/net/wireless/b43/wa.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/wa.c 2008-04-19 13:54:59.000000000 +0200
-@@ -204,42 +204,43 @@
- b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]);
- }
-
-+static void b43_write_null_nst(struct b43_wldev *dev)
-+{
-+ int i;
-+
-+ for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
-+ b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, 0);
-+}
-+
-+static void b43_write_nst(struct b43_wldev *dev, const u16 *nst)
-+{
-+ int i;
-+
-+ for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
-+ b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, nst[i]);
-+}
-+
- static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */
- {
- struct b43_phy *phy = &dev->phy;
-- int i;
-
- if (phy->type == B43_PHYTYPE_A) {
- if (phy->rev <= 1)
-- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
-- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
-- i, 0);
-+ b43_write_null_nst(dev);
- else if (phy->rev == 2)
-- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
-- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
-- i, b43_tab_noisescalea2[i]);
-+ b43_write_nst(dev, b43_tab_noisescalea2);
- else if (phy->rev == 3)
-- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
-- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
-- i, b43_tab_noisescalea3[i]);
-+ b43_write_nst(dev, b43_tab_noisescalea3);
- else
-- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
-- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
-- i, b43_tab_noisescaleg3[i]);
-+ b43_write_nst(dev, b43_tab_noisescaleg3);
- } else {
- if (phy->rev >= 6) {
- if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
-- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
-- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
-- i, b43_tab_noisescaleg3[i]);
-+ b43_write_nst(dev, b43_tab_noisescaleg3);
- else
-- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
-- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
-- i, b43_tab_noisescaleg2[i]);
-+ b43_write_nst(dev, b43_tab_noisescaleg2);
- } else {
-- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
-- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
-- i, b43_tab_noisescaleg1[i]);
-+ b43_write_nst(dev, b43_tab_noisescaleg1);
- }
- }
- }
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/xmit.c linux-2.6.25/drivers/net/wireless/b43/xmit.c
---- linux-2.6.25.old/drivers/net/wireless/b43/xmit.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/xmit.c 2008-04-19 13:54:59.000000000 +0200
-@@ -30,48 +30,51 @@
- #include "xmit.h"
- #include "phy.h"
- #include "dma.h"
-+#include "pio.h"
-
-
--/* Extract the bitrate out of a CCK PLCP header. */
--static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp)
-+/* Extract the bitrate index out of a CCK PLCP header. */
-+static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
- {
- switch (plcp->raw[0]) {
- case 0x0A:
-- return B43_CCK_RATE_1MB;
-+ return 0;
- case 0x14:
-- return B43_CCK_RATE_2MB;
-+ return 1;
- case 0x37:
-- return B43_CCK_RATE_5MB;
-+ return 2;
- case 0x6E:
-- return B43_CCK_RATE_11MB;
-+ return 3;
- }
- B43_WARN_ON(1);
-- return 0;
-+ return -1;
- }
-
--/* Extract the bitrate out of an OFDM PLCP header. */
--static u8 b43_plcp_get_bitrate_ofdm(struct b43_plcp_hdr6 *plcp)
-+/* Extract the bitrate index out of an OFDM PLCP header. */
-+static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
- {
-+ int base = aphy ? 0 : 4;
-+
- switch (plcp->raw[0] & 0xF) {
- case 0xB:
-- return B43_OFDM_RATE_6MB;
-+ return base + 0;
- case 0xF:
-- return B43_OFDM_RATE_9MB;
-+ return base + 1;
- case 0xA:
-- return B43_OFDM_RATE_12MB;
-+ return base + 2;
- case 0xE:
-- return B43_OFDM_RATE_18MB;
-+ return base + 3;
- case 0x9:
-- return B43_OFDM_RATE_24MB;
-+ return base + 4;
- case 0xD:
-- return B43_OFDM_RATE_36MB;
-+ return base + 5;
- case 0x8:
-- return B43_OFDM_RATE_48MB;
-+ return base + 6;
- case 0xC:
-- return B43_OFDM_RATE_54MB;
-+ return base + 7;
- }
- B43_WARN_ON(1);
-- return 0;
-+ return -1;
- }
-
- u8 b43_plcp_get_ratecode_cck(const u8 bitrate)
-@@ -191,6 +194,7 @@
- (const struct ieee80211_hdr *)fragment_data;
- int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
- u16 fctl = le16_to_cpu(wlhdr->frame_control);
-+ struct ieee80211_rate *fbrate;
- u8 rate, rate_fb;
- int rate_ofdm, rate_fb_ofdm;
- unsigned int plcp_fragment_len;
-@@ -200,9 +204,11 @@
-
- memset(txhdr, 0, sizeof(*txhdr));
-
-- rate = txctl->tx_rate;
-+ WARN_ON(!txctl->tx_rate);
-+ rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB;
- rate_ofdm = b43_is_ofdm_rate(rate);
-- rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate;
-+ fbrate = txctl->alt_retry_rate ? : txctl->tx_rate;
-+ rate_fb = fbrate->hw_value;
- rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
-
- if (rate_ofdm)
-@@ -221,11 +227,10 @@
- * use the original dur_id field. */
- txhdr->dur_fb = wlhdr->duration_id;
- } else {
-- int fbrate_base100kbps = B43_RATE_TO_BASE100KBPS(rate_fb);
- txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
- txctl->vif,
- fragment_len,
-- fbrate_base100kbps);
-+ fbrate);
- }
-
- plcp_fragment_len = fragment_len + FCS_LEN;
-@@ -287,7 +292,7 @@
- phy_ctl |= B43_TXH_PHY_ENC_OFDM;
- else
- phy_ctl |= B43_TXH_PHY_ENC_CCK;
-- if (dev->short_preamble)
-+ if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
- phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
-
- switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) {
-@@ -332,7 +337,8 @@
- int rts_rate_ofdm, rts_rate_fb_ofdm;
- struct b43_plcp_hdr6 *plcp;
-
-- rts_rate = txctl->rts_cts_rate;
-+ WARN_ON(!txctl->rts_cts_rate);
-+ rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
- rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
- rts_rate_fb = b43_calc_fallback_rate(rts_rate);
- rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
-@@ -506,7 +512,7 @@
- u16 phystat0, phystat3, chanstat, mactime;
- u32 macstat;
- u16 chanid;
-- u8 jssi;
-+ u16 phytype;
- int padding;
-
- memset(&status, 0, sizeof(status));
-@@ -514,10 +520,10 @@
- /* Get metadata about the frame from the header. */
- phystat0 = le16_to_cpu(rxhdr->phy_status0);
- phystat3 = le16_to_cpu(rxhdr->phy_status3);
-- jssi = rxhdr->jssi;
- macstat = le32_to_cpu(rxhdr->mac_status);
- mactime = le16_to_cpu(rxhdr->mac_time);
- chanstat = le16_to_cpu(rxhdr->channel);
-+ phytype = chanstat & B43_RX_CHAN_PHYTYPE;
-
- if (macstat & B43_RX_MAC_FCSERR)
- dev->wl->ieee_stats.dot11FCSErrorCount++;
-@@ -567,26 +573,40 @@
- }
- }
-
-- status.ssi = b43_rssi_postprocess(dev, jssi,
-+ /* Link quality statistics */
-+ status.noise = dev->stats.link_noise;
-+ if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) {
-+// s8 rssi = max(rxhdr->power0, rxhdr->power1);
-+ //TODO: Find out what the rssi value is (dBm or percentage?)
-+ // and also find out what the maximum possible value is.
-+ // Fill status.ssi and status.signal fields.
-+ } else {
-+ status.ssi = b43_rssi_postprocess(dev, rxhdr->jssi,
- (phystat0 & B43_RX_PHYST0_OFDM),
- (phystat0 & B43_RX_PHYST0_GAINCTL),
- (phystat3 & B43_RX_PHYST3_TRSTATE));
-- status.noise = dev->stats.link_noise;
- /* the next line looks wrong, but is what mac80211 wants */
-- status.signal = (jssi * 100) / B43_RX_MAX_SSI;
-+ status.signal = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
-+ }
-+
- if (phystat0 & B43_RX_PHYST0_OFDM)
-- status.rate = b43_plcp_get_bitrate_ofdm(plcp);
-+ status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
-+ phytype == B43_PHYTYPE_A);
- else
-- status.rate = b43_plcp_get_bitrate_cck(plcp);
-+ status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
- status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
-
- /*
-- * If monitors are present get full 64-bit timestamp. This
-- * code assumes we get to process the packet within 16 bits
-- * of timestamp, i.e. about 65 milliseconds after the PHY
-- * received the first symbol.
-+ * All frames on monitor interfaces and beacons always need a full
-+ * 64-bit timestamp. Monitor interfaces need it for diagnostic
-+ * purposes and beacons for IBSS merging.
-+ * This code assumes we get to process the packet within 16 bits
-+ * of timestamp, i.e. about 65 milliseconds after the PHY received
-+ * the first symbol.
- */
-- if (dev->wl->radiotap_enabled) {
-+ if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
-+ == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
-+ dev->wl->radiotap_enabled) {
- u16 low_mactime_now;
-
- b43_tsf_read(dev, &status.mactime);
-@@ -601,29 +621,28 @@
- chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
- switch (chanstat & B43_RX_CHAN_PHYTYPE) {
- case B43_PHYTYPE_A:
-- status.phymode = MODE_IEEE80211A;
-+ status.band = IEEE80211_BAND_5GHZ;
- B43_WARN_ON(1);
- /* FIXME: We don't really know which value the "chanid" contains.
- * So the following assignment might be wrong. */
-- status.channel = chanid;
-- status.freq = b43_channel_to_freq_5ghz(status.channel);
-+ status.freq = b43_channel_to_freq_5ghz(chanid);
- break;
- case B43_PHYTYPE_G:
-- status.phymode = MODE_IEEE80211G;
-+ status.band = IEEE80211_BAND_2GHZ;
- /* chanid is the radio channel cookie value as used
- * to tune the radio. */
- status.freq = chanid + 2400;
-- status.channel = b43_freq_to_channel_2ghz(status.freq);
- break;
- case B43_PHYTYPE_N:
-- status.phymode = 0xDEAD /*FIXME MODE_IEEE80211N*/;
- /* chanid is the SHM channel cookie. Which is the plain
- * channel number in b43. */
-- status.channel = chanid;
-- if (chanstat & B43_RX_CHAN_5GHZ)
-- status.freq = b43_freq_to_channel_5ghz(status.freq);
-- else
-- status.freq = b43_freq_to_channel_2ghz(status.freq);
-+ if (chanstat & B43_RX_CHAN_5GHZ) {
-+ status.band = IEEE80211_BAND_5GHZ;
-+ status.freq = b43_freq_to_channel_5ghz(chanid);
-+ } else {
-+ status.band = IEEE80211_BAND_2GHZ;
-+ status.freq = b43_freq_to_channel_2ghz(chanid);
-+ }
- break;
- default:
- B43_WARN_ON(1);
-@@ -657,67 +676,54 @@
- dev->wl->ieee_stats.dot11RTSSuccessCount++;
- }
-
-+ if (b43_using_pio_transfers(dev))
-+ b43_pio_handle_txstatus(dev, status);
-+ else
- b43_dma_handle_txstatus(dev, status);
- }
-
--/* Handle TX status report as received through DMA/PIO queues */
--void b43_handle_hwtxstatus(struct b43_wldev *dev,
-- const struct b43_hwtxstatus *hw)
--{
-- struct b43_txstatus status;
-- u8 tmp;
--
-- status.cookie = le16_to_cpu(hw->cookie);
-- status.seq = le16_to_cpu(hw->seq);
-- status.phy_stat = hw->phy_stat;
-- tmp = hw->count;
-- status.frame_count = (tmp >> 4);
-- status.rts_count = (tmp & 0x0F);
-- tmp = hw->flags;
-- status.supp_reason = ((tmp & 0x1C) >> 2);
-- status.pm_indicated = !!(tmp & 0x80);
-- status.intermediate = !!(tmp & 0x40);
-- status.for_ampdu = !!(tmp & 0x20);
-- status.acked = !!(tmp & 0x02);
-+/* Fill out the mac80211 TXstatus report based on the b43-specific
-+ * txstatus report data. This returns a boolean whether the frame was
-+ * successfully transmitted. */
-+bool b43_fill_txstatus_report(struct ieee80211_tx_status *report,
-+ const struct b43_txstatus *status)
-+{
-+ bool frame_success = 1;
-
-- b43_handle_txstatus(dev, &status);
-+ if (status->acked) {
-+ /* The frame was ACKed. */
-+ report->flags |= IEEE80211_TX_STATUS_ACK;
-+ } else {
-+ /* The frame was not ACKed... */
-+ if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
-+ /* ...but we expected an ACK. */
-+ frame_success = 0;
-+ report->excessive_retries = 1;
-+ }
-+ }
-+ if (status->frame_count == 0) {
-+ /* The frame was not transmitted at all. */
-+ report->retry_count = 0;
-+ } else
-+ report->retry_count = status->frame_count - 1;
-+
-+ return frame_success;
- }
-
- /* Stop any TX operation on the device (suspend the hardware queues) */
- void b43_tx_suspend(struct b43_wldev *dev)
- {
-+ if (b43_using_pio_transfers(dev))
-+ b43_pio_tx_suspend(dev);
-+ else
- b43_dma_tx_suspend(dev);
- }
-
- /* Resume any TX operation on the device (resume the hardware queues) */
- void b43_tx_resume(struct b43_wldev *dev)
- {
-+ if (b43_using_pio_transfers(dev))
-+ b43_pio_tx_resume(dev);
-+ else
- b43_dma_tx_resume(dev);
- }
--
--#if 0
--static void upload_qos_parms(struct b43_wldev *dev,
-- const u16 * parms, u16 offset)
--{
-- int i;
--
-- for (i = 0; i < B43_NR_QOSPARMS; i++) {
-- b43_shm_write16(dev, B43_SHM_SHARED,
-- offset + (i * 2), parms[i]);
-- }
--}
--#endif
--
--/* Initialize the QoS parameters */
--void b43_qos_init(struct b43_wldev *dev)
--{
-- /* FIXME: This function must probably be called from the mac80211
-- * config callback. */
-- return;
--
-- b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
-- //FIXME kill magic
-- b43_write16(dev, 0x688, b43_read16(dev, 0x688) | 0x4);
--
-- /*TODO: We might need some stack support here to get the values. */
--}
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43/xmit.h linux-2.6.25/drivers/net/wireless/b43/xmit.h
---- linux-2.6.25.old/drivers/net/wireless/b43/xmit.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43/xmit.h 2008-04-19 13:54:59.000000000 +0200
-@@ -207,25 +207,24 @@
- B43_TXST_SUPP_ABNACK, /* Afterburner NACK */
- };
-
--/* Transmit Status as received through DMA/PIO on old chips */
--struct b43_hwtxstatus {
-- PAD_BYTES(4);
-- __le16 cookie;
-- u8 flags;
-- u8 count;
-- PAD_BYTES(2);
-- __le16 seq;
-- u8 phy_stat;
-- PAD_BYTES(1);
--} __attribute__ ((__packed__));
--
- /* Receive header for v4 firmware. */
- struct b43_rxhdr_fw4 {
- __le16 frame_len; /* Frame length */
- PAD_BYTES(2);
- __le16 phy_status0; /* PHY RX Status 0 */
-+ union {
-+ /* RSSI for A/B/G-PHYs */
-+ struct {
- __u8 jssi; /* PHY RX Status 1: JSSI */
- __u8 sig_qual; /* PHY RX Status 1: Signal Quality */
-+ } __attribute__ ((__packed__));
-+
-+ /* RSSI for N-PHYs */
-+ struct {
-+ __s8 power0; /* PHY RX Status 1: Power 0 */
-+ __s8 power1; /* PHY RX Status 1: Power 1 */
-+ } __attribute__ ((__packed__));
-+ } __attribute__ ((__packed__));
- __le16 phy_status2; /* PHY RX Status 2 */
- __le16 phy_status3; /* PHY RX Status 3 */
- __le32 mac_status; /* MAC RX status */
-@@ -295,25 +294,12 @@
-
- void b43_handle_txstatus(struct b43_wldev *dev,
- const struct b43_txstatus *status);
--
--void b43_handle_hwtxstatus(struct b43_wldev *dev,
-- const struct b43_hwtxstatus *hw);
-+bool b43_fill_txstatus_report(struct ieee80211_tx_status *report,
-+ const struct b43_txstatus *status);
-
- void b43_tx_suspend(struct b43_wldev *dev);
- void b43_tx_resume(struct b43_wldev *dev);
-
--#define B43_NR_QOSPARMS 22
--enum {
-- B43_QOSPARM_TXOP = 0,
-- B43_QOSPARM_CWMIN,
-- B43_QOSPARM_CWMAX,
-- B43_QOSPARM_CWCUR,
-- B43_QOSPARM_AIFS,
-- B43_QOSPARM_BSLOTS,
-- B43_QOSPARM_REGGAP,
-- B43_QOSPARM_STATUS,
--};
--void b43_qos_init(struct b43_wldev *dev);
-
- /* Helper functions for converting the key-table index from "firmware-format"
- * to "raw-format" and back. The firmware API changed for this at some revision.
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43legacy/b43legacy.h linux-2.6.25/drivers/net/wireless/b43legacy/b43legacy.h
---- linux-2.6.25.old/drivers/net/wireless/b43legacy/b43legacy.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43legacy/b43legacy.h 2008-04-19 13:54:59.000000000 +0200
-@@ -97,6 +97,7 @@
- #define B43legacy_MMIO_RADIO_HWENABLED_LO 0x49A
- #define B43legacy_MMIO_GPIO_CONTROL 0x49C
- #define B43legacy_MMIO_GPIO_MASK 0x49E
-+#define B43legacy_MMIO_TSF_CFP_PRETBTT 0x612
- #define B43legacy_MMIO_TSF_0 0x632 /* core rev < 3 only */
- #define B43legacy_MMIO_TSF_1 0x634 /* core rev < 3 only */
- #define B43legacy_MMIO_TSF_2 0x636 /* core rev < 3 only */
-@@ -130,19 +131,27 @@
- #define B43legacy_SHM_SH_HOSTFHI 0x0060 /* Hostflags ucode opts (high) */
- /* SHM_SHARED crypto engine */
- #define B43legacy_SHM_SH_KEYIDXBLOCK 0x05D4 /* Key index/algorithm block */
--/* SHM_SHARED beacon variables */
-+/* SHM_SHARED beacon/AP variables */
-+#define B43legacy_SHM_SH_DTIMP 0x0012 /* DTIM period */
-+#define B43legacy_SHM_SH_BTL0 0x0018 /* Beacon template length 0 */
-+#define B43legacy_SHM_SH_BTL1 0x001A /* Beacon template length 1 */
-+#define B43legacy_SHM_SH_BTSFOFF 0x001C /* Beacon TSF offset */
-+#define B43legacy_SHM_SH_TIMPOS 0x001E /* TIM position in beacon */
- #define B43legacy_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word */
- /* SHM_SHARED ACK/CTS control */
- #define B43legacy_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word */
- /* SHM_SHARED probe response variables */
--#define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */
-+#define B43legacy_SHM_SH_PRTLEN 0x004A /* Probe Response template length */
- #define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */
-+#define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */
- /* SHM_SHARED rate tables */
- /* SHM_SHARED microcode soft registers */
- #define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */
- #define B43legacy_SHM_SH_UCODEPATCH 0x0002 /* Microcode patchlevel */
- #define B43legacy_SHM_SH_UCODEDATE 0x0004 /* Microcode date */
- #define B43legacy_SHM_SH_UCODETIME 0x0006 /* Microcode time */
-+#define B43legacy_SHM_SH_SPUWKUP 0x0094 /* pre-wakeup for synth PU in us */
-+#define B43legacy_SHM_SH_PRETBTT 0x0096 /* pre-TBTT in us */
-
- #define B43legacy_UCODEFLAGS_OFFSET 0x005E
-
-@@ -199,6 +208,13 @@
- #define B43legacy_MACCTL_TBTTHOLD 0x10000000 /* TBTT Hold */
- #define B43legacy_MACCTL_GMODE 0x80000000 /* G Mode */
-
-+/* MAC Command bitfield */
-+#define B43legacy_MACCMD_BEACON0_VALID 0x00000001 /* Beacon 0 in template RAM is busy/valid */
-+#define B43legacy_MACCMD_BEACON1_VALID 0x00000002 /* Beacon 1 in template RAM is busy/valid */
-+#define B43legacy_MACCMD_DFQ_VALID 0x00000004 /* Directed frame queue valid (IBSS PS mode, ATIM) */
-+#define B43legacy_MACCMD_CCA 0x00000008 /* Clear channel assessment */
-+#define B43legacy_MACCMD_BGNOISE 0x00000010 /* Background noise */
-+
- /* 802.11 core specific TM State Low flags */
- #define B43legacy_TMSLOW_GMODE 0x20000000 /* G Mode Enable */
- #define B43legacy_TMSLOW_PLLREFSEL 0x00200000 /* PLL Freq Ref Select */
-@@ -317,15 +333,7 @@
- # undef assert
- #endif
- #ifdef CONFIG_B43LEGACY_DEBUG
--# define B43legacy_WARN_ON(expr) \
-- do { \
-- if (unlikely((expr))) { \
-- printk(KERN_INFO PFX "Test (%s) failed at:" \
-- " %s:%d:%s()\n", \
-- #expr, __FILE__, \
-- __LINE__, __FUNCTION__); \
-- } \
-- } while (0)
-+# define B43legacy_WARN_ON(x) WARN_ON(x)
- # define B43legacy_BUG_ON(expr) \
- do { \
- if (unlikely((expr))) { \
-@@ -336,7 +344,9 @@
- } while (0)
- # define B43legacy_DEBUG 1
- #else
--# define B43legacy_WARN_ON(x) do { /* nothing */ } while (0)
-+/* This will evaluate the argument even if debugging is disabled. */
-+static inline bool __b43legacy_warn_on_dummy(bool x) { return x; }
-+# define B43legacy_WARN_ON(x) __b43legacy_warn_on_dummy(unlikely(!!(x)))
- # define B43legacy_BUG_ON(x) do { /* nothing */ } while (0)
- # define B43legacy_DEBUG 0
- #endif
-@@ -392,10 +402,6 @@
- u8 possible_phymodes;
- /* GMODE bit enabled in MACCTL? */
- bool gmode;
-- /* Possible ieee80211 subsystem hwmodes for this PHY.
-- * Which mode is selected, depends on thr GMODE enabled bit */
--#define B43legacy_MAX_PHYHWMODES 2
-- struct ieee80211_hw_mode hwmodes[B43legacy_MAX_PHYHWMODES];
-
- /* Analog Type */
- u8 analog;
-@@ -598,6 +604,12 @@
- u8 nr_devs;
-
- bool radiotap_enabled;
-+
-+ /* The beacon we are currently using (AP or IBSS mode).
-+ * This beacon stuff is protected by the irq_lock. */
-+ struct sk_buff *current_beacon;
-+ bool beacon0_uploaded;
-+ bool beacon1_uploaded;
- };
-
- /* Pointers to the firmware data and meta information about it. */
-@@ -649,7 +661,7 @@
-
- bool __using_pio; /* Using pio rather than dma. */
- bool bad_frames_preempt;/* Use "Bad Frames Preemption". */
-- bool reg124_set_0x4; /* Variable to keep track of IRQ. */
-+ bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */
- bool short_preamble; /* TRUE if using short preamble. */
- bool short_slot; /* TRUE if using short slot timing. */
- bool radio_hw_enable; /* State of radio hardware enable bit. */
-@@ -696,9 +708,6 @@
- u8 max_nr_keys;
- struct b43legacy_key key[58];
-
-- /* Cached beacon template while uploading the template. */
-- struct sk_buff *cached_beacon;
--
- /* Firmware data */
- struct b43legacy_firmware fw;
-
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43legacy/main.c linux-2.6.25/drivers/net/wireless/b43legacy/main.c
---- linux-2.6.25.old/drivers/net/wireless/b43legacy/main.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43legacy/main.c 2008-04-19 16:24:28.000000000 +0200
-@@ -96,27 +96,28 @@
- * get concurrency issues */
- #define RATETAB_ENT(_rateid, _flags) \
- { \
-- .rate = B43legacy_RATE_TO_100KBPS(_rateid), \
-- .val = (_rateid), \
-- .val2 = (_rateid), \
-+ .bitrate = B43legacy_RATE_TO_100KBPS(_rateid), \
-+ .hw_value = (_rateid), \
- .flags = (_flags), \
- }
-+/*
-+ * NOTE: When changing this, sync with xmit.c's
-+ * b43legacy_plcp_get_bitrate_idx_* functions!
-+ */
- static struct ieee80211_rate __b43legacy_ratetable[] = {
-- RATETAB_ENT(B43legacy_CCK_RATE_1MB, IEEE80211_RATE_CCK),
-- RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_CCK_2),
-- RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_CCK_2),
-- RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_CCK_2),
-- RATETAB_ENT(B43legacy_OFDM_RATE_6MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43legacy_OFDM_RATE_9MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43legacy_OFDM_RATE_12MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43legacy_OFDM_RATE_18MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43legacy_OFDM_RATE_24MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43legacy_OFDM_RATE_36MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43legacy_OFDM_RATE_48MB, IEEE80211_RATE_OFDM),
-- RATETAB_ENT(B43legacy_OFDM_RATE_54MB, IEEE80211_RATE_OFDM),
-+ RATETAB_ENT(B43legacy_CCK_RATE_1MB, 0),
-+ RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE),
-+ RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE),
-+ RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE),
-+ RATETAB_ENT(B43legacy_OFDM_RATE_6MB, 0),
-+ RATETAB_ENT(B43legacy_OFDM_RATE_9MB, 0),
-+ RATETAB_ENT(B43legacy_OFDM_RATE_12MB, 0),
-+ RATETAB_ENT(B43legacy_OFDM_RATE_18MB, 0),
-+ RATETAB_ENT(B43legacy_OFDM_RATE_24MB, 0),
-+ RATETAB_ENT(B43legacy_OFDM_RATE_36MB, 0),
-+ RATETAB_ENT(B43legacy_OFDM_RATE_48MB, 0),
-+ RATETAB_ENT(B43legacy_OFDM_RATE_54MB, 0),
- };
--#define b43legacy_a_ratetable (__b43legacy_ratetable + 4)
--#define b43legacy_a_ratetable_size 8
- #define b43legacy_b_ratetable (__b43legacy_ratetable + 0)
- #define b43legacy_b_ratetable_size 4
- #define b43legacy_g_ratetable (__b43legacy_ratetable + 0)
-@@ -124,14 +125,8 @@
-
- #define CHANTAB_ENT(_chanid, _freq) \
- { \
-- .chan = (_chanid), \
-- .freq = (_freq), \
-- .val = (_chanid), \
-- .flag = IEEE80211_CHAN_W_SCAN | \
-- IEEE80211_CHAN_W_ACTIVE_SCAN | \
-- IEEE80211_CHAN_W_IBSS, \
-- .power_level = 0x0A, \
-- .antenna_max = 0xFF, \
-+ .center_freq = (_freq), \
-+ .hw_value = (_chanid), \
- }
- static struct ieee80211_channel b43legacy_bg_chantable[] = {
- CHANTAB_ENT(1, 2412),
-@@ -149,7 +144,20 @@
- CHANTAB_ENT(13, 2472),
- CHANTAB_ENT(14, 2484),
- };
--#define b43legacy_bg_chantable_size ARRAY_SIZE(b43legacy_bg_chantable)
-+
-+static struct ieee80211_supported_band b43legacy_band_2GHz_BPHY = {
-+ .channels = b43legacy_bg_chantable,
-+ .n_channels = ARRAY_SIZE(b43legacy_bg_chantable),
-+ .bitrates = b43legacy_b_ratetable,
-+ .n_bitrates = b43legacy_b_ratetable_size,
-+};
-+
-+static struct ieee80211_supported_band b43legacy_band_2GHz_GPHY = {
-+ .channels = b43legacy_bg_chantable,
-+ .n_channels = ARRAY_SIZE(b43legacy_bg_chantable),
-+ .bitrates = b43legacy_g_ratetable,
-+ .n_bitrates = b43legacy_g_ratetable_size,
-+};
-
- static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev);
- static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev);
-@@ -797,9 +805,8 @@
- {
- b43legacy_jssi_write(dev, 0x7F7F7F7F);
- b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
-- b43legacy_read32(dev,
-- B43legacy_MMIO_MACCMD)
-- | (1 << 4));
-+ b43legacy_read32(dev, B43legacy_MMIO_MACCMD)
-+ | B43legacy_MACCMD_BGNOISE);
- B43legacy_WARN_ON(dev->noisecalc.channel_at_start !=
- dev->phy.channel);
- }
-@@ -888,18 +895,18 @@
- if (1/*FIXME: the last PSpoll frame was sent successfully */)
- b43legacy_power_saving_ctl_bits(dev, -1, -1);
- }
-- dev->reg124_set_0x4 = 0;
- if (b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS))
-- dev->reg124_set_0x4 = 1;
-+ dev->dfq_valid = 1;
- }
-
- static void handle_irq_atim_end(struct b43legacy_wldev *dev)
- {
-- if (!dev->reg124_set_0x4) /*FIXME rename this variable*/
-- return;
-+ if (dev->dfq_valid) {
- b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
- b43legacy_read32(dev, B43legacy_MMIO_MACCMD)
-- | 0x4);
-+ | B43legacy_MACCMD_DFQ_VALID);
-+ dev->dfq_valid = 0;
-+ }
- }
-
- static void handle_irq_pmq(struct b43legacy_wldev *dev)
-@@ -955,32 +962,77 @@
- u16 ram_offset,
- u16 shm_size_offset, u8 rate)
- {
-- int len;
-- const u8 *data;
-
-- B43legacy_WARN_ON(!dev->cached_beacon);
-- len = min((size_t)dev->cached_beacon->len,
-+ unsigned int i, len, variable_len;
-+ const struct ieee80211_mgmt *bcn;
-+ const u8 *ie;
-+ bool tim_found = 0;
-+
-+ bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
-+ len = min((size_t)dev->wl->current_beacon->len,
- 0x200 - sizeof(struct b43legacy_plcp_hdr6));
-- data = (const u8 *)(dev->cached_beacon->data);
-- b43legacy_write_template_common(dev, data,
-- len, ram_offset,
-+
-+ b43legacy_write_template_common(dev, (const u8 *)bcn, len, ram_offset,
- shm_size_offset, rate);
-+
-+ /* Find the position of the TIM and the DTIM_period value
-+ * and write them to SHM. */
-+ ie = bcn->u.beacon.variable;
-+ variable_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
-+ for (i = 0; i < variable_len - 2; ) {
-+ uint8_t ie_id, ie_len;
-+
-+ ie_id = ie[i];
-+ ie_len = ie[i + 1];
-+ if (ie_id == 5) {
-+ u16 tim_position;
-+ u16 dtim_period;
-+ /* This is the TIM Information Element */
-+
-+ /* Check whether the ie_len is in the beacon data range. */
-+ if (variable_len < ie_len + 2 + i)
-+ break;
-+ /* A valid TIM is at least 4 bytes long. */
-+ if (ie_len < 4)
-+ break;
-+ tim_found = 1;
-+
-+ tim_position = sizeof(struct b43legacy_plcp_hdr6);
-+ tim_position += offsetof(struct ieee80211_mgmt,
-+ u.beacon.variable);
-+ tim_position += i;
-+
-+ dtim_period = ie[i + 3];
-+
-+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
-+ B43legacy_SHM_SH_TIMPOS, tim_position);
-+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
-+ B43legacy_SHM_SH_DTIMP, dtim_period);
-+ break;
-+ }
-+ i += ie_len + 2;
-+ }
-+ if (!tim_found) {
-+ b43legacywarn(dev->wl, "Did not find a valid TIM IE in the "
-+ "beacon template packet. AP or IBSS operation "
-+ "may be broken.\n");
-+ }
- }
-
- static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
- u16 shm_offset, u16 size,
-- u8 rate)
-+ struct ieee80211_rate *rate)
- {
- struct b43legacy_plcp_hdr4 plcp;
- u32 tmp;
- __le16 dur;
-
- plcp.data = 0;
-- b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
-+ b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate);
- dur = ieee80211_generic_frame_duration(dev->wl->hw,
- dev->wl->vif,
- size,
-- B43legacy_RATE_TO_100KBPS(rate));
-+ rate);
- /* Write PLCP in two parts and timing for packet transfer */
- tmp = le32_to_cpu(plcp.data);
- b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset,
-@@ -997,45 +1049,44 @@
- * 2) Patching duration field
- * 3) Stripping TIM
- */
--static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev,
-- u16 *dest_size, u8 rate)
-+static const u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev,
-+ u16 *dest_size,
-+ struct ieee80211_rate *rate)
- {
- const u8 *src_data;
- u8 *dest_data;
-- u16 src_size;
-- u16 elem_size;
-- u16 src_pos;
-- u16 dest_pos;
-+ u16 src_size, elem_size, src_pos, dest_pos;
- __le16 dur;
- struct ieee80211_hdr *hdr;
-+ size_t ie_start;
-+
-+ src_size = dev->wl->current_beacon->len;
-+ src_data = (const u8 *)dev->wl->current_beacon->data;
-+
-+ /* Get the start offset of the variable IEs in the packet. */
-+ ie_start = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
-+ B43legacy_WARN_ON(ie_start != offsetof(struct ieee80211_mgmt,
-+ u.beacon.variable));
-
-- B43legacy_WARN_ON(!dev->cached_beacon);
-- src_size = dev->cached_beacon->len;
-- src_data = (const u8 *)dev->cached_beacon->data;
--
-- if (unlikely(src_size < 0x24)) {
-- b43legacydbg(dev->wl, "b43legacy_generate_probe_resp: "
-- "invalid beacon\n");
-+ if (B43legacy_WARN_ON(src_size < ie_start))
- return NULL;
-- }
-
- dest_data = kmalloc(src_size, GFP_ATOMIC);
- if (unlikely(!dest_data))
- return NULL;
-
-- /* 0x24 is offset of first variable-len Information-Element
-- * in beacon frame.
-- */
-- memcpy(dest_data, src_data, 0x24);
-- src_pos = 0x24;
-- dest_pos = 0x24;
-- for (; src_pos < src_size - 2; src_pos += elem_size) {
-+ /* Copy the static data and all Information Elements, except the TIM. */
-+ memcpy(dest_data, src_data, ie_start);
-+ src_pos = ie_start;
-+ dest_pos = ie_start;
-+ for ( ; src_pos < src_size - 2; src_pos += elem_size) {
- elem_size = src_data[src_pos + 1] + 2;
-- if (src_data[src_pos] != 0x05) { /* TIM */
-- memcpy(dest_data + dest_pos, src_data + src_pos,
-- elem_size);
-- dest_pos += elem_size;
-+ if (src_data[src_pos] == 5) {
-+ /* This is the TIM. */
-+ continue;
- }
-+ memcpy(dest_data + dest_pos, src_data + src_pos, elem_size);
-+ dest_pos += elem_size;
- }
- *dest_size = dest_pos;
- hdr = (struct ieee80211_hdr *)dest_data;
-@@ -1046,7 +1097,7 @@
- dur = ieee80211_generic_frame_duration(dev->wl->hw,
- dev->wl->vif,
- *dest_size,
-- B43legacy_RATE_TO_100KBPS(rate));
-+ rate);
- hdr->duration_id = dur;
-
- return dest_data;
-@@ -1054,13 +1105,13 @@
-
- static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
- u16 ram_offset,
-- u16 shm_size_offset, u8 rate)
-+ u16 shm_size_offset,
-+ struct ieee80211_rate *rate)
- {
-- u8 *probe_resp_data;
-+ const u8 *probe_resp_data;
- u16 size;
-
-- B43legacy_WARN_ON(!dev->cached_beacon);
-- size = dev->cached_beacon->len;
-+ size = dev->wl->current_beacon->len;
- probe_resp_data = b43legacy_generate_probe_resp(dev, &size, rate);
- if (unlikely(!probe_resp_data))
- return;
-@@ -1069,59 +1120,37 @@
- * all possible basic rates
- */
- b43legacy_write_probe_resp_plcp(dev, 0x31A, size,
-- B43legacy_CCK_RATE_1MB);
-+ &b43legacy_b_ratetable[0]);
- b43legacy_write_probe_resp_plcp(dev, 0x32C, size,
-- B43legacy_CCK_RATE_2MB);
-+ &b43legacy_b_ratetable[1]);
- b43legacy_write_probe_resp_plcp(dev, 0x33E, size,
-- B43legacy_CCK_RATE_5MB);
-+ &b43legacy_b_ratetable[2]);
- b43legacy_write_probe_resp_plcp(dev, 0x350, size,
-- B43legacy_CCK_RATE_11MB);
-+ &b43legacy_b_ratetable[3]);
-
- size = min((size_t)size,
- 0x200 - sizeof(struct b43legacy_plcp_hdr6));
- b43legacy_write_template_common(dev, probe_resp_data,
- size, ram_offset,
-- shm_size_offset, rate);
-+ shm_size_offset, rate->bitrate);
- kfree(probe_resp_data);
- }
-
--static int b43legacy_refresh_cached_beacon(struct b43legacy_wldev *dev,
-+/* Asynchronously update the packet templates in template RAM.
-+ * Locking: Requires wl->irq_lock to be locked. */
-+static void b43legacy_update_templates(struct b43legacy_wl *wl,
- struct sk_buff *beacon)
- {
-- if (dev->cached_beacon)
-- kfree_skb(dev->cached_beacon);
-- dev->cached_beacon = beacon;
--
-- return 0;
--}
--
--static void b43legacy_update_templates(struct b43legacy_wldev *dev)
--{
-- u32 status;
--
-- B43legacy_WARN_ON(!dev->cached_beacon);
--
-- b43legacy_write_beacon_template(dev, 0x68, 0x18,
-- B43legacy_CCK_RATE_1MB);
-- b43legacy_write_beacon_template(dev, 0x468, 0x1A,
-- B43legacy_CCK_RATE_1MB);
-- b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
-- B43legacy_CCK_RATE_11MB);
--
-- status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
-- status |= 0x03;
-- b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status);
--}
--
--static void b43legacy_refresh_templates(struct b43legacy_wldev *dev,
-- struct sk_buff *beacon)
--{
-- int err;
--
-- err = b43legacy_refresh_cached_beacon(dev, beacon);
-- if (unlikely(err))
-- return;
-- b43legacy_update_templates(dev);
-+ /* This is the top half of the ansynchronous beacon update. The bottom
-+ * half is the beacon IRQ. Beacon update must be asynchronous to avoid
-+ * sending an invalid beacon. This can happen for example, if the
-+ * firmware transmits a beacon while we are updating it. */
-+
-+ if (wl->current_beacon)
-+ dev_kfree_skb_any(wl->current_beacon);
-+ wl->current_beacon = beacon;
-+ wl->beacon0_uploaded = 0;
-+ wl->beacon1_uploaded = 0;
- }
-
- static void b43legacy_set_ssid(struct b43legacy_wldev *dev,
-@@ -1162,38 +1191,37 @@
-
- static void handle_irq_beacon(struct b43legacy_wldev *dev)
- {
-- u32 status;
-+ struct b43legacy_wl *wl = dev->wl;
-+ u32 cmd;
-
-- if (!b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
-+ if (!b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP))
- return;
-
-- dev->irq_savedstate &= ~B43legacy_IRQ_BEACON;
-- status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
-+ /* This is the bottom half of the asynchronous beacon update. */
-
-- if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) {
-- /* ACK beacon IRQ. */
-- b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
-- B43legacy_IRQ_BEACON);
-- dev->irq_savedstate |= B43legacy_IRQ_BEACON;
-- if (dev->cached_beacon)
-- kfree_skb(dev->cached_beacon);
-- dev->cached_beacon = NULL;
-- return;
-- }
-- if (!(status & 0x1)) {
-- b43legacy_write_beacon_template(dev, 0x68, 0x18,
-+ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
-+ if (!(cmd & B43legacy_MACCMD_BEACON0_VALID)) {
-+ if (!wl->beacon0_uploaded) {
-+ b43legacy_write_beacon_template(dev, 0x68,
-+ B43legacy_SHM_SH_BTL0,
- B43legacy_CCK_RATE_1MB);
-- status |= 0x1;
-- b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
-- status);
-- }
-- if (!(status & 0x2)) {
-- b43legacy_write_beacon_template(dev, 0x468, 0x1A,
-+ b43legacy_write_probe_resp_template(dev, 0x268,
-+ B43legacy_SHM_SH_PRTLEN,
-+ &__b43legacy_ratetable[3]);
-+ wl->beacon0_uploaded = 1;
-+ }
-+ cmd |= B43legacy_MACCMD_BEACON0_VALID;
-+ }
-+ if (!(cmd & B43legacy_MACCMD_BEACON1_VALID)) {
-+ if (!wl->beacon1_uploaded) {
-+ b43legacy_write_beacon_template(dev, 0x468,
-+ B43legacy_SHM_SH_BTL1,
- B43legacy_CCK_RATE_1MB);
-- status |= 0x2;
-- b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
-- status);
-+ wl->beacon1_uploaded = 1;
-+ }
-+ cmd |= B43legacy_MACCMD_BEACON1_VALID;
- }
-+ b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
- }
-
- static void handle_irq_ucode_debug(struct b43legacy_wldev *dev)
-@@ -2552,13 +2580,15 @@
- antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx);
-
- mutex_lock(&wl->mutex);
-+ dev = wl->current_dev;
-+ phy = &dev->phy;
-
- /* Switch the PHY mode (if necessary). */
-- switch (conf->phymode) {
-- case MODE_IEEE80211B:
-+ switch (conf->channel->band) {
-+ case IEEE80211_BAND_2GHZ:
-+ if (phy->type == B43legacy_PHYTYPE_B)
- new_phymode = B43legacy_PHYMODE_B;
-- break;
-- case MODE_IEEE80211G:
-+ else
- new_phymode = B43legacy_PHYMODE_G;
- break;
- default:
-@@ -2567,8 +2597,6 @@
- err = b43legacy_switch_phymode(wl, new_phymode);
- if (err)
- goto out_unlock_mutex;
-- dev = wl->current_dev;
-- phy = &dev->phy;
-
- /* Disable IRQs while reconfiguring the device.
- * This makes it possible to drop the spinlock throughout
-@@ -2584,8 +2612,8 @@
-
- /* Switch to the requested channel.
- * The firmware takes care of races with the TX handler. */
-- if (conf->channel_val != phy->channel)
-- b43legacy_radio_selectchannel(dev, conf->channel_val, 0);
-+ if (conf->channel->hw_value != phy->channel)
-+ b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
-
- /* Enable/Disable ShortSlot timing. */
- if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME))
-@@ -2702,7 +2730,7 @@
- B43legacy_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP);
- b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len);
- if (conf->beacon)
-- b43legacy_refresh_templates(dev, conf->beacon);
-+ b43legacy_update_templates(wl, conf->beacon);
- }
- b43legacy_write_mac_bssid_templates(dev);
- }
-@@ -2920,7 +2948,7 @@
- static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev)
- {
- /* Flags */
-- dev->reg124_set_0x4 = 0;
-+ dev->dfq_valid = 0;
-
- /* Stats */
- memset(&dev->stats, 0, sizeof(dev->stats));
-@@ -2979,6 +3007,34 @@
- b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
- }
-
-+static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev,
-+ bool idle) {
-+ u16 pu_delay = 1050;
-+
-+ if (b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS) || idle)
-+ pu_delay = 500;
-+ if ((dev->phy.radio_ver == 0x2050) && (dev->phy.radio_rev == 8))
-+ pu_delay = max(pu_delay, (u16)2400);
-+
-+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
-+ B43legacy_SHM_SH_SPUWKUP, pu_delay);
-+}
-+
-+/* Set the TSF CFP pre-TargetBeaconTransmissionTime. */
-+static void b43legacy_set_pretbtt(struct b43legacy_wldev *dev)
-+{
-+ u16 pretbtt;
-+
-+ /* The time value is in microseconds. */
-+ if (b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS))
-+ pretbtt = 2;
-+ else
-+ pretbtt = 250;
-+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
-+ B43legacy_SHM_SH_PRETBTT, pretbtt);
-+ b43legacy_write16(dev, B43legacy_MMIO_TSF_CFP_PRETBTT, pretbtt);
-+}
-+
- /* Shutdown a wireless core */
- /* Locking: wl->mutex */
- static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
-@@ -3015,6 +3071,11 @@
- kfree(phy->tssi2dbm);
- kfree(phy->lo_control);
- phy->lo_control = NULL;
-+ if (dev->wl->current_beacon) {
-+ dev_kfree_skb_any(dev->wl->current_beacon);
-+ dev->wl->current_beacon = NULL;
-+ }
-+
- ssb_device_disable(dev->dev, 0);
- ssb_bus_may_powerdown(dev->dev->bus);
- }
-@@ -3160,9 +3221,7 @@
- if (err)
- goto err_chip_exit;
-
-- b43legacy_write16(dev, 0x0612, 0x0050);
-- b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0416, 0x0050);
-- b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0414, 0x01F4);
-+ b43legacy_set_synth_pu_delay(dev, 1);
-
- ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
- b43legacy_upload_card_macaddress(dev);
-@@ -3218,6 +3277,8 @@
-
- spin_lock_irqsave(&wl->irq_lock, flags);
- b43legacy_adjust_opmode(dev);
-+ b43legacy_set_pretbtt(dev);
-+ b43legacy_set_synth_pu_delay(dev, 0);
- b43legacy_upload_card_macaddress(dev);
- spin_unlock_irqrestore(&wl->irq_lock, flags);
-
-@@ -3339,6 +3400,41 @@
- return err;
- }
-
-+static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
-+ int aid, int set)
-+{
-+ struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
-+ struct sk_buff *beacon;
-+ unsigned long flags;
-+
-+ /* We could modify the existing beacon and set the aid bit in the TIM
-+ * field, but that would probably require resizing and moving of data
-+ * within the beacon template. Simply request a new beacon and let
-+ * mac80211 do the hard work. */
-+ beacon = ieee80211_beacon_get(hw, wl->vif, NULL);
-+ if (unlikely(!beacon))
-+ return -ENOMEM;
-+ spin_lock_irqsave(&wl->irq_lock, flags);
-+ b43legacy_update_templates(wl, beacon);
-+ spin_unlock_irqrestore(&wl->irq_lock, flags);
-+
-+ return 0;
-+}
-+
-+static int b43legacy_op_ibss_beacon_update(struct ieee80211_hw *hw,
-+ struct sk_buff *beacon,
-+ struct ieee80211_tx_control *ctl)
-+{
-+ struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&wl->irq_lock, flags);
-+ b43legacy_update_templates(wl, beacon);
-+ spin_unlock_irqrestore(&wl->irq_lock, flags);
-+
-+ return 0;
-+}
-+
- static const struct ieee80211_ops b43legacy_hw_ops = {
- .tx = b43legacy_op_tx,
- .conf_tx = b43legacy_op_conf_tx,
-@@ -3352,6 +3448,8 @@
- .start = b43legacy_op_start,
- .stop = b43legacy_op_stop,
- .set_retry_limit = b43legacy_op_set_retry_limit,
-+ .set_tim = b43legacy_op_beacon_set_tim,
-+ .beacon_update = b43legacy_op_ibss_beacon_update,
- };
-
- /* Hard-reset the chip. Do not call this directly.
-@@ -3400,48 +3498,19 @@
- int have_gphy)
- {
- struct ieee80211_hw *hw = dev->wl->hw;
-- struct ieee80211_hw_mode *mode;
- struct b43legacy_phy *phy = &dev->phy;
-- int cnt = 0;
-- int err;
-
- phy->possible_phymodes = 0;
-- for (; 1; cnt++) {
- if (have_bphy) {
-- B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES);
-- mode = &phy->hwmodes[cnt];
--
-- mode->mode = MODE_IEEE80211B;
-- mode->num_channels = b43legacy_bg_chantable_size;
-- mode->channels = b43legacy_bg_chantable;
-- mode->num_rates = b43legacy_b_ratetable_size;
-- mode->rates = b43legacy_b_ratetable;
-- err = ieee80211_register_hwmode(hw, mode);
-- if (err)
-- return err;
--
-+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
-+ &b43legacy_band_2GHz_BPHY;
- phy->possible_phymodes |= B43legacy_PHYMODE_B;
-- have_bphy = 0;
-- continue;
- }
-- if (have_gphy) {
-- B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES);
-- mode = &phy->hwmodes[cnt];
--
-- mode->mode = MODE_IEEE80211G;
-- mode->num_channels = b43legacy_bg_chantable_size;
-- mode->channels = b43legacy_bg_chantable;
-- mode->num_rates = b43legacy_g_ratetable_size;
-- mode->rates = b43legacy_g_ratetable;
-- err = ieee80211_register_hwmode(hw, mode);
-- if (err)
-- return err;
-
-+ if (have_gphy) {
-+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
-+ &b43legacy_band_2GHz_GPHY;
- phy->possible_phymodes |= B43legacy_PHYMODE_G;
-- have_gphy = 0;
-- continue;
-- }
-- break;
- }
-
- return 0;
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/b43legacy/xmit.c linux-2.6.25/drivers/net/wireless/b43legacy/xmit.c
---- linux-2.6.25.old/drivers/net/wireless/b43legacy/xmit.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/b43legacy/xmit.c 2008-04-19 13:54:59.000000000 +0200
-@@ -37,45 +37,48 @@
-
-
- /* Extract the bitrate out of a CCK PLCP header. */
--static u8 b43legacy_plcp_get_bitrate_cck(struct b43legacy_plcp_hdr6 *plcp)
-+static u8 b43legacy_plcp_get_bitrate_idx_cck(struct b43legacy_plcp_hdr6 *plcp)
- {
- switch (plcp->raw[0]) {
- case 0x0A:
-- return B43legacy_CCK_RATE_1MB;
-+ return 0;
- case 0x14:
-- return B43legacy_CCK_RATE_2MB;
-+ return 1;
- case 0x37:
-- return B43legacy_CCK_RATE_5MB;
-+ return 2;
- case 0x6E:
-- return B43legacy_CCK_RATE_11MB;
-+ return 3;
- }
- B43legacy_BUG_ON(1);
-- return 0;
-+ return -1;
- }
-
- /* Extract the bitrate out of an OFDM PLCP header. */
--static u8 b43legacy_plcp_get_bitrate_ofdm(struct b43legacy_plcp_hdr6 *plcp)
-+static u8 b43legacy_plcp_get_bitrate_idx_ofdm(struct b43legacy_plcp_hdr6 *plcp,
-+ bool aphy)
- {
-+ int base = aphy ? 0 : 4;
-+
- switch (plcp->raw[0] & 0xF) {
- case 0xB:
-- return B43legacy_OFDM_RATE_6MB;
-+ return base + 0;
- case 0xF:
-- return B43legacy_OFDM_RATE_9MB;
-+ return base + 1;
- case 0xA:
-- return B43legacy_OFDM_RATE_12MB;
-+ return base + 2;
- case 0xE:
-- return B43legacy_OFDM_RATE_18MB;
-+ return base + 3;
- case 0x9:
-- return B43legacy_OFDM_RATE_24MB;
-+ return base + 4;
- case 0xD:
-- return B43legacy_OFDM_RATE_36MB;
-+ return base + 5;
- case 0x8:
-- return B43legacy_OFDM_RATE_48MB;
-+ return base + 6;
- case 0xC:
-- return B43legacy_OFDM_RATE_54MB;
-+ return base + 7;
- }
- B43legacy_BUG_ON(1);
-- return 0;
-+ return -1;
- }
-
- u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate)
-@@ -192,7 +195,7 @@
- int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
- u16 fctl;
- u8 rate;
-- u8 rate_fb;
-+ struct ieee80211_rate *rate_fb;
- int rate_ofdm;
- int rate_fb_ofdm;
- unsigned int plcp_fragment_len;
-@@ -204,16 +207,16 @@
-
- memset(txhdr, 0, sizeof(*txhdr));
-
-- rate = txctl->tx_rate;
-+ rate = txctl->tx_rate->hw_value;
- rate_ofdm = b43legacy_is_ofdm_rate(rate);
-- rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate;
-- rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb);
-+ rate_fb = txctl->alt_retry_rate ? : txctl->tx_rate;
-+ rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
-
- txhdr->mac_frame_ctl = wlhdr->frame_control;
- memcpy(txhdr->tx_receiver, wlhdr->addr1, 6);
-
- /* Calculate duration for fallback rate */
-- if ((rate_fb == rate) ||
-+ if ((rate_fb->hw_value == rate) ||
- (wlhdr->duration_id & cpu_to_le16(0x8000)) ||
- (wlhdr->duration_id == cpu_to_le16(0))) {
- /* If the fallback rate equals the normal rate or the
-@@ -221,11 +224,10 @@
- * use the original dur_id field. */
- txhdr->dur_fb = wlhdr->duration_id;
- } else {
-- int fbrate_base100kbps = B43legacy_RATE_TO_100KBPS(rate_fb);
- txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
- txctl->vif,
- fragment_len,
-- fbrate_base100kbps);
-+ rate_fb);
- }
-
- plcp_fragment_len = fragment_len + FCS_LEN;
-@@ -266,7 +268,7 @@
- rate);
- b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
- (&txhdr->plcp_fb), plcp_fragment_len,
-- rate_fb);
-+ rate_fb->hw_value);
-
- /* PHY TX Control word */
- if (rate_ofdm)
-@@ -310,7 +312,7 @@
- int rts_rate_ofdm;
- int rts_rate_fb_ofdm;
-
-- rts_rate = txctl->rts_cts_rate;
-+ rts_rate = txctl->rts_cts_rate->hw_value;
- rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate);
- rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
- rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
-@@ -536,19 +538,24 @@
- (phystat3 & B43legacy_RX_PHYST3_TRSTATE));
- status.noise = dev->stats.link_noise;
- status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI;
-+ /* change to support A PHY */
- if (phystat0 & B43legacy_RX_PHYST0_OFDM)
-- status.rate = b43legacy_plcp_get_bitrate_ofdm(plcp);
-+ status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
- else
-- status.rate = b43legacy_plcp_get_bitrate_cck(plcp);
-+ status.rate_idx = b43legacy_plcp_get_bitrate_idx_cck(plcp);
- status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT);
-
- /*
-- * If monitors are present get full 64-bit timestamp. This
-- * code assumes we get to process the packet within 16 bits
-- * of timestamp, i.e. about 65 milliseconds after the PHY
-- * received the first symbol.
-+ * All frames on monitor interfaces and beacons always need a full
-+ * 64-bit timestamp. Monitor interfaces need it for diagnostic
-+ * purposes and beacons for IBSS merging.
-+ * This code assumes we get to process the packet within 16 bits
-+ * of timestamp, i.e. about 65 milliseconds after the PHY received
-+ * the first symbol.
- */
-- if (dev->wl->radiotap_enabled) {
-+ if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
-+ == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
-+ dev->wl->radiotap_enabled) {
- u16 low_mactime_now;
-
- b43legacy_tsf_read(dev, &status.mactime);
-@@ -564,14 +571,9 @@
- B43legacy_RX_CHAN_ID_SHIFT;
- switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) {
- case B43legacy_PHYTYPE_B:
-- status.phymode = MODE_IEEE80211B;
-- status.freq = chanid + 2400;
-- status.channel = b43legacy_freq_to_channel_bg(chanid + 2400);
-- break;
- case B43legacy_PHYTYPE_G:
-- status.phymode = MODE_IEEE80211G;
-+ status.band = IEEE80211_BAND_2GHZ;
- status.freq = chanid + 2400;
-- status.channel = b43legacy_freq_to_channel_bg(chanid + 2400);
- break;
- default:
- b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n",
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c linux-2.6.25/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
---- linux-2.6.25.old/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,556 +0,0 @@
--/*
--
-- Broadcom BCM43xx wireless driver
--
-- debugfs driver debugging code
--
-- Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; see the file COPYING. If not, write to
-- the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
-- Boston, MA 02110-1301, USA.
--
--*/
--
--
--
--#include <linux/fs.h>
--#include <linux/debugfs.h>
--#include <linux/slab.h>
--#include <linux/netdevice.h>
--#include <linux/pci.h>
--#include <asm/io.h>
--
--#include "bcm43xx.h"
--#include "bcm43xx_main.h"
--#include "bcm43xx_debugfs.h"
--#include "bcm43xx_dma.h"
--#include "bcm43xx_pio.h"
--#include "bcm43xx_xmit.h"
--
--#define REALLY_BIG_BUFFER_SIZE (1024*256)
--
--static struct bcm43xx_debugfs fs;
--static char really_big_buffer[REALLY_BIG_BUFFER_SIZE];
--static DECLARE_MUTEX(big_buffer_sem);
--
--
--static ssize_t write_file_dummy(struct file *file, const char __user *buf,
-- size_t count, loff_t *ppos)
--{
-- return count;
--}
--
--static int open_file_generic(struct inode *inode, struct file *file)
--{
-- file->private_data = inode->i_private;
-- return 0;
--}
--
--#define fappend(fmt, x...) pos += snprintf(buf + pos, len - pos, fmt , ##x)
--
--static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
-- size_t count, loff_t *ppos)
--{
-- const size_t len = REALLY_BIG_BUFFER_SIZE;
--
-- struct bcm43xx_private *bcm = file->private_data;
-- char *buf = really_big_buffer;
-- size_t pos = 0;
-- ssize_t res;
-- struct net_device *net_dev;
-- struct pci_dev *pci_dev;
-- unsigned long flags;
-- u16 tmp16;
-- int i;
--
-- down(&big_buffer_sem);
--
-- mutex_lock(&bcm->mutex);
-- spin_lock_irqsave(&bcm->irq_lock, flags);
-- if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
-- fappend("Board not initialized.\n");
-- goto out;
-- }
-- net_dev = bcm->net_dev;
-- pci_dev = bcm->pci_dev;
--
-- /* This is where the information is written to the "devinfo" file */
-- fappend("*** %s devinfo ***\n", net_dev->name);
-- fappend("vendor: 0x%04x device: 0x%04x\n",
-- pci_dev->vendor, pci_dev->device);
-- fappend("subsystem_vendor: 0x%04x subsystem_device: 0x%04x\n",
-- pci_dev->subsystem_vendor, pci_dev->subsystem_device);
-- fappend("IRQ: %d\n", bcm->irq);
-- fappend("mmio_addr: 0x%p\n", bcm->mmio_addr);
-- fappend("chip_id: 0x%04x chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev);
-- if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16)))
-- fappend("Radio disabled by hardware!\n");
-- if ((bcm->core_80211[0].rev < 3) && !(bcm43xx_read16(bcm, 0x049A) & (1 << 4)))
-- fappend("Radio disabled by hardware!\n");
-- fappend("board_vendor: 0x%04x board_type: 0x%04x\n", bcm->board_vendor,
-- bcm->board_type);
--
-- fappend("\nCores:\n");
--#define fappend_core(name, info) fappend("core \"" name "\" %s, %s, id: 0x%04x, " \
-- "rev: 0x%02x, index: 0x%02x\n", \
-- (info).available \
-- ? "available" : "nonavailable", \
-- (info).enabled \
-- ? "enabled" : "disabled", \
-- (info).id, (info).rev, (info).index)
-- fappend_core("CHIPCOMMON", bcm->core_chipcommon);
-- fappend_core("PCI", bcm->core_pci);
-- fappend_core("first 80211", bcm->core_80211[0]);
-- fappend_core("second 80211", bcm->core_80211[1]);
--#undef fappend_core
-- tmp16 = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
-- fappend("LEDs: ");
-- for (i = 0; i < BCM43xx_NR_LEDS; i++)
-- fappend("%d ", !!(tmp16 & (1 << i)));
-- fappend("\n");
--
--out:
-- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-- mutex_unlock(&bcm->mutex);
-- res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-- up(&big_buffer_sem);
-- return res;
--}
--
--static ssize_t drvinfo_read_file(struct file *file, char __user *userbuf,
-- size_t count, loff_t *ppos)
--{
-- const size_t len = REALLY_BIG_BUFFER_SIZE;
--
-- char *buf = really_big_buffer;
-- size_t pos = 0;
-- ssize_t res;
--
-- down(&big_buffer_sem);
--
-- /* This is where the information is written to the "driver" file */
-- fappend(KBUILD_MODNAME " driver\n");
-- fappend("Compiled at: %s %s\n", __DATE__, __TIME__);
--
-- res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-- up(&big_buffer_sem);
-- return res;
--}
--
--static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
-- size_t count, loff_t *ppos)
--{
-- const size_t len = REALLY_BIG_BUFFER_SIZE;
--
-- struct bcm43xx_private *bcm = file->private_data;
-- char *buf = really_big_buffer;
-- size_t pos = 0;
-- ssize_t res;
-- unsigned long flags;
--
-- down(&big_buffer_sem);
-- mutex_lock(&bcm->mutex);
-- spin_lock_irqsave(&bcm->irq_lock, flags);
-- if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
-- fappend("Board not initialized.\n");
-- goto out;
-- }
--
-- /* This is where the information is written to the "sprom_dump" file */
-- fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
--
--out:
-- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-- mutex_unlock(&bcm->mutex);
-- res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-- up(&big_buffer_sem);
-- return res;
--}
--
--static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
-- size_t count, loff_t *ppos)
--{
-- const size_t len = REALLY_BIG_BUFFER_SIZE;
--
-- struct bcm43xx_private *bcm = file->private_data;
-- char *buf = really_big_buffer;
-- size_t pos = 0;
-- ssize_t res;
-- unsigned long flags;
-- u64 tsf;
--
-- down(&big_buffer_sem);
-- mutex_lock(&bcm->mutex);
-- spin_lock_irqsave(&bcm->irq_lock, flags);
-- if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
-- fappend("Board not initialized.\n");
-- goto out;
-- }
-- bcm43xx_tsf_read(bcm, &tsf);
-- fappend("0x%08x%08x\n",
-- (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
-- (unsigned int)(tsf & 0xFFFFFFFFULL));
--
--out:
-- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-- mutex_unlock(&bcm->mutex);
-- res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-- up(&big_buffer_sem);
-- return res;
--}
--
--static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
-- size_t count, loff_t *ppos)
--{
-- struct bcm43xx_private *bcm = file->private_data;
-- char *buf = really_big_buffer;
-- ssize_t buf_size;
-- ssize_t res;
-- unsigned long flags;
-- unsigned long long tsf;
--
-- buf_size = min(count, sizeof (really_big_buffer) - 1);
-- down(&big_buffer_sem);
-- if (copy_from_user(buf, user_buf, buf_size)) {
-- res = -EFAULT;
-- goto out_up;
-- }
-- mutex_lock(&bcm->mutex);
-- spin_lock_irqsave(&bcm->irq_lock, flags);
-- if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
-- printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
-- res = -EFAULT;
-- goto out_unlock;
-- }
-- if (sscanf(buf, "%lli", &tsf) != 1) {
-- printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n");
-- res = -EINVAL;
-- goto out_unlock;
-- }
-- bcm43xx_tsf_write(bcm, tsf);
-- mmiowb();
-- res = buf_size;
--
--out_unlock:
-- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-- mutex_unlock(&bcm->mutex);
--out_up:
-- up(&big_buffer_sem);
-- return res;
--}
--
--static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
-- size_t count, loff_t *ppos)
--{
-- const size_t len = REALLY_BIG_BUFFER_SIZE;
--
-- struct bcm43xx_private *bcm = file->private_data;
-- char *buf = really_big_buffer;
-- size_t pos = 0;
-- ssize_t res;
-- unsigned long flags;
-- struct bcm43xx_dfsentry *e;
-- struct bcm43xx_xmitstatus *status;
-- int i, cnt, j = 0;
--
-- down(&big_buffer_sem);
-- mutex_lock(&bcm->mutex);
-- spin_lock_irqsave(&bcm->irq_lock, flags);
--
-- fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
-- BCM43xx_NR_LOGGED_XMITSTATUS);
-- e = bcm->dfsentry;
-- if (e->xmitstatus_printing == 0) {
-- /* At the beginning, make a copy of all data to avoid
-- * concurrency, as this function is called multiple
-- * times for big logs. Without copying, the data might
-- * change between reads. This would result in total trash.
-- */
-- e->xmitstatus_printing = 1;
-- e->saved_xmitstatus_ptr = e->xmitstatus_ptr;
-- e->saved_xmitstatus_cnt = e->xmitstatus_cnt;
-- memcpy(e->xmitstatus_print_buffer, e->xmitstatus_buffer,
-- BCM43xx_NR_LOGGED_XMITSTATUS * sizeof(*(e->xmitstatus_buffer)));
-- }
-- i = e->saved_xmitstatus_ptr - 1;
-- if (i < 0)
-- i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
-- cnt = e->saved_xmitstatus_cnt;
-- while (cnt) {
-- status = e->xmitstatus_print_buffer + i;
-- fappend("0x%02x: cookie: 0x%04x, flags: 0x%02x, "
-- "cnt1: 0x%02x, cnt2: 0x%02x, seq: 0x%04x, "
-- "unk: 0x%04x\n", j,
-- status->cookie, status->flags,
-- status->cnt1, status->cnt2, status->seq,
-- status->unknown);
-- j++;
-- cnt--;
-- i--;
-- if (i < 0)
-- i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
-- }
--
-- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-- res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-- spin_lock_irqsave(&bcm->irq_lock, flags);
-- if (*ppos == pos) {
-- /* Done. Drop the copied data. */
-- e->xmitstatus_printing = 0;
-- }
-- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-- mutex_unlock(&bcm->mutex);
-- up(&big_buffer_sem);
-- return res;
--}
--
--static ssize_t restart_write_file(struct file *file, const char __user *user_buf,
-- size_t count, loff_t *ppos)
--{
-- struct bcm43xx_private *bcm = file->private_data;
-- char *buf = really_big_buffer;
-- ssize_t buf_size;
-- ssize_t res;
-- unsigned long flags;
--
-- buf_size = min(count, sizeof (really_big_buffer) - 1);
-- down(&big_buffer_sem);
-- if (copy_from_user(buf, user_buf, buf_size)) {
-- res = -EFAULT;
-- goto out_up;
-- }
-- mutex_lock(&(bcm)->mutex);
-- spin_lock_irqsave(&(bcm)->irq_lock, flags);
-- if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
-- printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
-- res = -EFAULT;
-- goto out_unlock;
-- }
-- if (count > 0 && buf[0] == '1') {
-- bcm43xx_controller_restart(bcm, "manually restarted");
-- res = count;
-- } else
-- res = -EINVAL;
--
--out_unlock:
-- spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
-- mutex_unlock(&(bcm)->mutex);
--out_up:
-- up(&big_buffer_sem);
-- return res;
--}
--
--#undef fappend
--
--
--static const struct file_operations devinfo_fops = {
-- .read = devinfo_read_file,
-- .write = write_file_dummy,
-- .open = open_file_generic,
--};
--
--static const struct file_operations spromdump_fops = {
-- .read = spromdump_read_file,
-- .write = write_file_dummy,
-- .open = open_file_generic,
--};
--
--static const struct file_operations drvinfo_fops = {
-- .read = drvinfo_read_file,
-- .write = write_file_dummy,
-- .open = open_file_generic,
--};
--
--static const struct file_operations tsf_fops = {
-- .read = tsf_read_file,
-- .write = tsf_write_file,
-- .open = open_file_generic,
--};
--
--static const struct file_operations txstat_fops = {
-- .read = txstat_read_file,
-- .write = write_file_dummy,
-- .open = open_file_generic,
--};
--
--static const struct file_operations restart_fops = {
-- .write = restart_write_file,
-- .open = open_file_generic,
--};
--
--
--void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
--{
-- struct bcm43xx_dfsentry *e;
-- char devdir[IFNAMSIZ];
--
-- assert(bcm);
-- e = kzalloc(sizeof(*e), GFP_KERNEL);
-- if (!e) {
-- printk(KERN_ERR PFX "out of memory\n");
-- return;
-- }
-- e->bcm = bcm;
-- e->xmitstatus_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
-- * sizeof(*(e->xmitstatus_buffer)),
-- GFP_KERNEL);
-- if (!e->xmitstatus_buffer) {
-- printk(KERN_ERR PFX "out of memory\n");
-- kfree(e);
-- return;
-- }
-- e->xmitstatus_print_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
-- * sizeof(*(e->xmitstatus_buffer)),
-- GFP_KERNEL);
-- if (!e->xmitstatus_print_buffer) {
-- printk(KERN_ERR PFX "out of memory\n");
-- kfree(e);
-- return;
-- }
--
--
-- bcm->dfsentry = e;
--
-- strncpy(devdir, bcm->net_dev->name, ARRAY_SIZE(devdir));
-- e->subdir = debugfs_create_dir(devdir, fs.root);
-- e->dentry_devinfo = debugfs_create_file("devinfo", 0444, e->subdir,
-- bcm, &devinfo_fops);
-- if (!e->dentry_devinfo)
-- printk(KERN_ERR PFX "debugfs: creating \"devinfo\" for \"%s\" failed!\n", devdir);
-- e->dentry_spromdump = debugfs_create_file("sprom_dump", 0444, e->subdir,
-- bcm, &spromdump_fops);
-- if (!e->dentry_spromdump)
-- printk(KERN_ERR PFX "debugfs: creating \"sprom_dump\" for \"%s\" failed!\n", devdir);
-- e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir,
-- bcm, &tsf_fops);
-- if (!e->dentry_tsf)
-- printk(KERN_ERR PFX "debugfs: creating \"tsf\" for \"%s\" failed!\n", devdir);
-- e->dentry_txstat = debugfs_create_file("tx_status", 0444, e->subdir,
-- bcm, &txstat_fops);
-- if (!e->dentry_txstat)
-- printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir);
-- e->dentry_restart = debugfs_create_file("restart", 0222, e->subdir,
-- bcm, &restart_fops);
-- if (!e->dentry_restart)
-- printk(KERN_ERR PFX "debugfs: creating \"restart\" for \"%s\" failed!\n", devdir);
--}
--
--void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
--{
-- struct bcm43xx_dfsentry *e;
--
-- if (!bcm)
-- return;
--
-- e = bcm->dfsentry;
-- assert(e);
-- debugfs_remove(e->dentry_spromdump);
-- debugfs_remove(e->dentry_devinfo);
-- debugfs_remove(e->dentry_tsf);
-- debugfs_remove(e->dentry_txstat);
-- debugfs_remove(e->dentry_restart);
-- debugfs_remove(e->subdir);
-- kfree(e->xmitstatus_buffer);
-- kfree(e->xmitstatus_print_buffer);
-- kfree(e);
--}
--
--void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
-- struct bcm43xx_xmitstatus *status)
--{
-- struct bcm43xx_dfsentry *e;
-- struct bcm43xx_xmitstatus *savedstatus;
--
-- /* This is protected by bcm->_lock */
-- e = bcm->dfsentry;
-- assert(e);
-- savedstatus = e->xmitstatus_buffer + e->xmitstatus_ptr;
-- memcpy(savedstatus, status, sizeof(*status));
-- e->xmitstatus_ptr++;
-- if (e->xmitstatus_ptr >= BCM43xx_NR_LOGGED_XMITSTATUS)
-- e->xmitstatus_ptr = 0;
-- if (e->xmitstatus_cnt < BCM43xx_NR_LOGGED_XMITSTATUS)
-- e->xmitstatus_cnt++;
--}
--
--void bcm43xx_debugfs_init(void)
--{
-- memset(&fs, 0, sizeof(fs));
-- fs.root = debugfs_create_dir(KBUILD_MODNAME, NULL);
-- if (!fs.root)
-- printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "\" subdir failed!\n");
-- fs.dentry_driverinfo = debugfs_create_file("driver", 0444, fs.root, NULL, &drvinfo_fops);
-- if (!fs.dentry_driverinfo)
-- printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "/driver\" failed!\n");
--}
--
--void bcm43xx_debugfs_exit(void)
--{
-- debugfs_remove(fs.dentry_driverinfo);
-- debugfs_remove(fs.root);
--}
--
--void bcm43xx_printk_dump(const char *data,
-- size_t size,
-- const char *description)
--{
-- size_t i;
-- char c;
--
-- printk(KERN_INFO PFX "Data dump (%s, %zd bytes):",
-- description, size);
-- for (i = 0; i < size; i++) {
-- c = data[i];
-- if (i % 8 == 0)
-- printk("\n" KERN_INFO PFX "0x%08zx: 0x%02x, ", i, c & 0xff);
-- else
-- printk("0x%02x, ", c & 0xff);
-- }
-- printk("\n");
--}
--
--void bcm43xx_printk_bitdump(const unsigned char *data,
-- size_t bytes, int msb_to_lsb,
-- const char *description)
--{
-- size_t i;
-- int j;
-- const unsigned char *d;
--
-- printk(KERN_INFO PFX "*** Bitdump (%s, %zd bytes, %s) ***",
-- description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB");
-- for (i = 0; i < bytes; i++) {
-- d = data + i;
-- if (i % 8 == 0)
-- printk("\n" KERN_INFO PFX "0x%08zx: ", i);
-- if (msb_to_lsb) {
-- for (j = 7; j >= 0; j--) {
-- if (*d & (1 << j))
-- printk("1");
-- else
-- printk("0");
-- }
-- } else {
-- for (j = 0; j < 8; j++) {
-- if (*d & (1 << j))
-- printk("1");
-- else
-- printk("0");
-- }
-- }
-- printk(" ");
-- }
-- printk("\n");
--}
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h linux-2.6.25/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
---- linux-2.6.25.old/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,118 +0,0 @@
--#ifndef BCM43xx_DEBUGFS_H_
--#define BCM43xx_DEBUGFS_H_
--
--struct bcm43xx_private;
--struct bcm43xx_xmitstatus;
--
--#ifdef CONFIG_BCM43XX_DEBUG
--
--#include <linux/list.h>
--#include <asm/semaphore.h>
--
--struct dentry;
--
--/* limited by the size of the "really_big_buffer" */
--#define BCM43xx_NR_LOGGED_XMITSTATUS 100
--
--struct bcm43xx_dfsentry {
-- struct dentry *subdir;
-- struct dentry *dentry_devinfo;
-- struct dentry *dentry_spromdump;
-- struct dentry *dentry_tsf;
-- struct dentry *dentry_txstat;
-- struct dentry *dentry_restart;
--
-- struct bcm43xx_private *bcm;
--
-- /* saved xmitstatus. */
-- struct bcm43xx_xmitstatus *xmitstatus_buffer;
-- int xmitstatus_ptr;
-- int xmitstatus_cnt;
-- /* We need a seperate buffer while printing to avoid
-- * concurrency issues. (New xmitstatus can arrive
-- * while we are printing).
-- */
-- struct bcm43xx_xmitstatus *xmitstatus_print_buffer;
-- int saved_xmitstatus_ptr;
-- int saved_xmitstatus_cnt;
-- int xmitstatus_printing;
--};
--
--struct bcm43xx_debugfs {
-- struct dentry *root;
-- struct dentry *dentry_driverinfo;
--};
--
--void bcm43xx_debugfs_init(void);
--void bcm43xx_debugfs_exit(void);
--void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm);
--void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm);
--void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
-- struct bcm43xx_xmitstatus *status);
--
--/* Debug helper: Dump binary data through printk. */
--void bcm43xx_printk_dump(const char *data,
-- size_t size,
-- const char *description);
--/* Debug helper: Dump bitwise binary data through printk. */
--void bcm43xx_printk_bitdump(const unsigned char *data,
-- size_t bytes, int msb_to_lsb,
-- const char *description);
--#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \
-- do { \
-- bcm43xx_printk_bitdump((const unsigned char *)(pointer), \
-- sizeof(*(pointer)), \
-- (msb_to_lsb), \
-- (description)); \
-- } while (0)
--
--#else /* CONFIG_BCM43XX_DEBUG*/
--
--static inline
--void bcm43xx_debugfs_init(void) { }
--static inline
--void bcm43xx_debugfs_exit(void) { }
--static inline
--void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) { }
--static inline
--void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) { }
--static inline
--void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
-- struct bcm43xx_xmitstatus *status) { }
--
--static inline
--void bcm43xx_printk_dump(const char *data,
-- size_t size,
-- const char *description)
--{
--}
--static inline
--void bcm43xx_printk_bitdump(const unsigned char *data,
-- size_t bytes, int msb_to_lsb,
-- const char *description)
--{
--}
--#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0)
--
--#endif /* CONFIG_BCM43XX_DEBUG*/
--
--/* Ugly helper macros to make incomplete code more verbose on runtime */
--#ifdef TODO
--# undef TODO
--#endif
--#define TODO() \
-- do { \
-- printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \
-- __FUNCTION__, __FILE__, __LINE__); \
-- } while (0)
--
--#ifdef FIXME
--# undef FIXME
--#endif
--#define FIXME() \
-- do { \
-- printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \
-- __FUNCTION__, __FILE__, __LINE__); \
-- } while (0)
--
--#endif /* BCM43xx_DEBUGFS_H_ */
-diff -Nbur linux-2.6.25.old/drivers/net/wireless/bcm43xx/bcm43xx_dma.c linux-2.6.25/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
---- linux-2.6.25.old/drivers/net/wireless/bcm43xx/bcm43xx_dma.c 2008-04-17 04:49:44.000000000 +0200
-+++ linux-2.6.25/drivers/net/wireless/bcm43xx/bcm43xx_dma.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,1263 +0,0 @@
--/*
--
-- Broadcom BCM43xx wireless driver
--
-- DMA ringbuffer and descriptor allocation/management
--
-- Copyright (c) 2005, 2006 Michael Buesch <mbuesch@freenet.de>
--
-- Some code in this file is derived from the b44.c driver
-- Copyright (C) 2002 David S. Miller
-- Copyright (C) Pekka Pietikainen
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; see the file COPYING. If not, write to
-- the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
-- Boston, MA 02110-1301, USA.
--
--*/
--
--#include "bcm43xx.h"
--#include "bcm43xx_dma.h"
--#include "bcm43xx_main.h"
--#include "bcm43xx_debugfs.h"
--#include "bcm43xx_power.h"
--#include "bcm43xx_xmit.h"
--
--#include <linux/dma-mapping.h>
--#include <linux/pci.h>
--#include <linux/delay.h>
--#include <linux/skbuff.h>
--
--
--static inline int free_slots(struct bcm43xx_dmaring *ring)
--{
-- return (ring->nr_slots - ring->used_slots);
--}
--
--static inline int next_slot(struct bcm43xx_dmaring *ring, int slot)
--{
-- assert(slot >= -1 && slot <= ring->nr_slots - 1);
-- if (slot == ring->nr_slots - 1)
-- return 0;
-- return slot + 1;
--}
--
--static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot)
--{
-- assert(slot >= 0 && slot <= ring->nr_slots - 1);
-- if (slot == 0)
-- return ring->nr_slots - 1;
-- return slot - 1;
--}
--
--/* Request a slot for usage. */
--static inline
--int request_slot(struct bcm43xx_dmaring *ring)
--{
-- int slot;
--
-- assert(ring->tx);
-- assert(!ring->suspended);
-- assert(free_slots(ring) != 0);
--
-- slot = next_slot(ring, ring->current_slot);
-- ring->current_slot = slot;
-- ring->used_slots++;
--
-- /* Check the number of available slots and suspend TX,
-- * if we are running low on free slots.
-- */
-- if (unlikely(free_slots(ring) < ring->suspend_mark)) {
-- netif_stop_queue(ring->bcm->net_dev);
-- ring->suspended = 1;
-- }
--#ifdef CONFIG_BCM43XX_DEBUG
-- if (ring->used_slots > ring->max_used_slots)
-- ring->max_used_slots = ring->used_slots;
--#endif /* CONFIG_BCM43XX_DEBUG*/
--
-- return slot;
--}
--
--/* Return a slot to the free slots. */
--static inline
--void return_slot(struct bcm43xx_dmaring *ring, int slot)
--{
-- assert(ring->tx);
--
-- ring->used_slots--;
--
-- /* Check if TX is suspended and check if we have
-- * enough free slots to resume it again.
-- */
-- if (unlikely(ring->suspended)) {
-- if (free_slots(ring) >= ring->resume_mark) {
-- ring->suspended = 0;
-- netif_wake_queue(ring->bcm->net_dev);
-- }
-- }
--}
--
--u16 bcm43xx_dmacontroller_base(int dma64bit, int controller_idx)
--{
-- static const u16 map64[] = {
-- BCM43xx_MMIO_DMA64_BASE0,
-- BCM43xx_MMIO_DMA64_BASE1,
-- BCM43xx_MMIO_DMA64_BASE2,
-- BCM43xx_MMIO_DMA64_BASE3,
-- BCM43xx_MMIO_DMA64_BASE4,
-- BCM43xx_MMIO_DMA64_BASE5,
-- };
-- static const u16 map32[] = {
-- BCM43xx_MMIO_DMA32_BASE0,
-- BCM43xx_MMIO_DMA32_BASE1,
-- BCM43xx_MMIO_DMA32_BASE2,
-- BCM43xx_MMIO_DMA32_BASE3,
-- BCM43xx_MMIO_DMA32_BASE4,
-- BCM43xx_MMIO_DMA32_BASE5,
-- };
--
-- if (dma64bit) {
-- assert(controller_idx >= 0 &&
-- controller_idx < ARRAY_SIZE(map64));
-- return map64[controller_idx];
-- }
-- assert(controller_idx >= 0 &&
-- controller_idx < ARRAY_SIZE(map32));
-- return map32[controller_idx];
--}
--
--static inline
--dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
-- unsigned char *buf,
-- size_t len,
-- int tx)
--{
-- dma_addr_t dmaaddr;
-- int direction = PCI_DMA_FROMDEVICE;
--
-- if (tx)
-- direction = PCI_DMA_TODEVICE;
--
-- dmaaddr = pci_map_single(ring->bcm->pci_dev,
-- buf, len,
-- direction);
--
-- return dmaaddr;
--}
--
--static inline
--void unmap_descbuffer(struct bcm43xx_dmaring *ring,
-- dma_addr_t addr,
-- size_t len,
-- int tx)
--{
-- if (tx) {
-- pci_unmap_single(ring->bcm->pci_dev,
-- addr, len,
-- PCI_DMA_TODEVICE);
-- } else {
-- pci_unmap_single(ring->bcm->pci_dev,
-- addr, len,
-- PCI_DMA_FROMDEVICE);
-- }
--}
--
--static inline
--void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
-- dma_addr_t addr,
-- size_t len)
--{
-- assert(!ring->tx);
--
-- pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
-- addr, len, PCI_DMA_FROMDEVICE);
--}
--
--static inline
--void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
-- dma_addr_t addr,
-- size_t len)
--{
-- assert(!ring->tx);
--
-- pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
-- addr, len, PCI_DMA_TODEVICE);
--}
--
--/* Unmap and free a descriptor buffer. */
--static inline
--void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
-- struct bcm43xx_dmadesc_meta *meta,
-- int irq_context)
--{
-- assert(meta->skb);
-- if (irq_context)
-- dev_kfree_skb_irq(meta->skb);
-- else
-- dev_kfree_skb(meta->skb);
-- meta->skb = NULL;
--}
--
--static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
--{
-- ring->descbase = pci_alloc_consistent(ring->bcm->pci_dev, BCM43xx_DMA_RINGMEMSIZE,
-- &(ring->dmabase));
-- if (!ring->descbase) {
-- /* Allocation may have failed due to pci_alloc_consistent
-- insisting on use of GFP_DMA, which is more restrictive
-- than necessary... */
-- struct dma_desc *rx_ring;
-- dma_addr_t rx_ring_dma;
--
-- rx_ring = kzalloc(BCM43xx_DMA_RINGMEMSIZE, GFP_KERNEL);
-- if (!rx_ring)
-- goto out_err;
--
-- rx_ring_dma = pci_map_single(ring->bcm->pci_dev, rx_ring,
-- BCM43xx_DMA_RINGMEMSIZE,
-- PCI_DMA_BIDIRECTIONAL);
--
-- if (pci_dma_mapping_error(rx_ring_dma) ||
-- rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
-- /* Sigh... */
-- if (!pci_dma_mapping_error(rx_ring_dma))
-- pci_unmap_single(ring->bcm->pci_dev,
-- rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
-- PCI_DMA_BIDIRECTIONAL);
-- rx_ring_dma = pci_map_single(ring->bcm->pci_dev,
-- rx_ring, BCM43xx_DMA_RINGMEMSIZE,
-- PCI_DMA_BIDIRECTIONAL);
-- if (pci_dma_mapping_error(rx_ring_dma) ||
-- rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
-- assert(0);
-- if (!pci_dma_mapping_error(rx_ring_dma))
-- pci_unmap_single(ring->bcm->pci_dev,
-- rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
-- PCI_DMA_BIDIRECTIONAL);
-- goto out_err;
-- }
-- }
--
-- ring->descbase = rx_ring;
-- ring->dmabase = rx_ring_dma;
-- }
-- memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
--
-- return 0;
--out_err:
-- printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
-- return -ENOMEM;
--}
--
--static void free_ringmemory(struct bcm43xx_dmaring *ring)
--{
-- struct device *dev = &(ring->bcm->pci_dev->dev);
--
-- dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
-- ring->descbase, ring->dmabase);
--}
--
--/* Reset the RX DMA channel */
--int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
-- u16 mmio_base, int dma64)
--{
-- int i;
-- u32 value;
-- u16 offset;
--
-- offset = dma64 ? BCM43xx_DMA64_RXCTL : BCM43xx_DMA32_RXCTL;
-- bcm43xx_write32(bcm, mmio_base + offset, 0);
-- for (i = 0; i < 1000; i++) {
-- offset = dma64 ? BCM43xx_DMA64_RXSTATUS : BCM43xx_DMA32_RXSTATUS;
-- value = bcm43xx_read32(bcm, mmio_base + offset);
-- if (dma64) {
-- value &= BCM43xx_DMA64_RXSTAT;
-- if (value == BCM43xx_DMA64_RXSTAT_DISABLED) {
-- i = -1;
-- break;
-- }
-- } else {
-- value &= BCM43xx_DMA32_RXSTATE;
-- if (value == BCM43xx_DMA32_RXSTAT_DISABLED) {
-- i = -1;
-- break;
-- }
-- }
-- udelay(10);
-- }
-- if (i != -1) {
-- printk(KERN_ERR PFX "Error: Wait on DMA RX status timed out.\n");
-- return -ENODEV;
-- }
--
-- return 0;
--}
--
--/* Reset the RX DMA channel */
--int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
-- u16 mmio_base, int dma64)
--{
-- int i;
-- u32 value;
-- u16 offset;
--
-- for (i = 0; i < 1000; i++) {
-- offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;
-- value = bcm43xx_read32(bcm, mmio_base + offset);
-- if (dma64) {
-- value &= BCM43xx_DMA64_TXSTAT;
-- if (value == BCM43xx_DMA64_TXSTAT_DISABLED ||
-- value == BCM43xx_DMA64_TXSTAT_IDLEWAIT ||
-- value == BCM43xx_DMA64_TXSTAT_STOPPED)
-- break;
-- } else {
-- value &= BCM43xx_DMA32_TXSTATE;
-- if (value == BCM43xx_DMA32_TXSTAT_DISABLED ||
-- value == BCM43xx_DMA32_TXSTAT_IDLEWAIT ||
-- value == BCM43xx_DMA32_TXSTAT_STOPPED)
-- break;
-- }
-- udelay(10);
-- }
-- offset = dma64 ? BCM43xx_DMA64_TXCTL : BCM43xx_DMA32_TXCTL;
-- bcm43xx_write32(bcm, mmio_base + offset, 0);
-- for (i = 0; i < 1000; i++) {
-- offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;
-- value = bcm43xx_read32(bcm, mmio_base + offset);
-- if (dma64) {
-- value &= BCM43xx_DMA64_TXSTAT;
-- if (value == BCM43xx_DMA64_TXSTAT_DISABLED) {
-- i = -1;
-- break;
-- }
-- } else {
-- value &= BCM43xx_DMA32_TXSTATE;
-- if (value == BCM43xx_DMA32_TXSTAT_DISABLED) {
-- i = -1;
-- break;
-- }
-- }
-- udelay(10);
-- }
-- if (i != -1) {
-- printk(KERN_ERR PFX "Error: Wait on DMA TX status timed out.\n");
-- return -ENODEV;
-- }
-- /* ensure the reset is completed. */
-- udelay(300);
--
-- return 0;
--}
--
--static void fill_descriptor(struct bcm43xx_dmaring *ring,
-- struct bcm43xx_dmadesc_generic *desc,
-- dma_addr_t dmaaddr,
-- u16 bufsize,
-- int start, int end, int irq)
--{
-- int slot;
--
-- slot = bcm43xx_dma_desc2idx(ring, desc);
-- assert(slot >= 0 && slot < ring->nr_slots);
--
-- if (ring->dma64) {
-- u32 ctl0 = 0, ctl1 = 0;
-- u32 addrlo, addrhi;
-- u32 addrext;
--
-- addrlo = (u32)(dmaaddr & 0xFFFFFFFF);
-- addrhi = (((u64)dmaaddr >> 32) & ~BCM43xx_DMA64_ROUTING);
-- addrext = (((u64)dmaaddr >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
-- addrhi |= ring->routing;
-- if (slot == ring->nr_slots - 1)
-- ctl0 |= BCM43xx_DMA64_DCTL0_DTABLEEND;
-- if (start)
-- ctl0 |= BCM43xx_DMA64_DCTL0_FRAMESTART;
-- if (end)
-- ctl0 |= BCM43xx_DMA64_DCTL0_FRAMEEND;
-- if (irq)
-- ctl0 |= BCM43xx_DMA64_DCTL0_IRQ;
-- ctl1 |= (bufsize - ring->frameoffset)
-- & BCM43xx_DMA64_DCTL1_BYTECNT;
-- ctl1 |= (addrext << BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT)
-- & BCM43xx_DMA64_DCTL1_ADDREXT_MASK;
--
-- desc->dma64.control0 = cpu_to_le32(ctl0);
-- desc->dma64.control1 = cpu_to_le32(ctl1);
-- desc->dma64.address_low = cpu_to_le32(addrlo);
-- desc->dma64.address_high = cpu_to_le32(addrhi);
-- } else {
-- u32 ctl;
-- u32 addr;
-- u32 addrext;
--
-- addr = (u32)(dmaaddr & ~BCM43xx_DMA32_ROUTING);
-- addrext = (u32)(dmaaddr & BCM43xx_DMA32_ROUTING)
-- >> BCM43xx_DMA32_ROUTING_SHIFT;
-- addr |= ring->routing;
-- ctl = (bufsize - ring->frameoffset)
-- & BCM43xx_DMA32_DCTL_BYTECNT;
-- if (slot == ring->nr_slots - 1)
-- ctl |= BCM43xx_DMA32_DCTL_DTABLEEND;
-- if (start)
-- ctl |= BCM43xx_DMA32_DCTL_FRAMESTART;
-- if (end)
-- ctl |= BCM43xx_DMA32_DCTL_FRAMEEND;
-- if (irq)
-- ctl |= BCM43xx_DMA32_DCTL_IRQ;
-- ctl |= (addrext << BCM43xx_DMA32_DCTL_ADDREXT_SHIFT)
-- & BCM43xx_DMA32_DCTL_ADDREXT_MASK;
--
-- desc->dma32.control = cpu_to_le32(ctl);
-- desc->dma32.address = cpu_to_le32(addr);
-- }
--}
--
--static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
-- struct bcm43xx_dmadesc_generic *desc,
-- struct bcm43xx_dmadesc_meta *meta,
-- gfp_t gfp_flags)
--{
-- struct bcm43xx_rxhdr *rxhdr;
-- struct bcm43xx_hwxmitstatus *xmitstat;
-- dma_addr_t dmaaddr;
-- struct sk_buff *skb;
--
-- assert(!ring->tx);
--
-- skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
-- if (unlikely(!skb))
-- return -ENOMEM;
-- dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
-- /* This hardware bug work-around adapted from the b44 driver.
-- The chip may be unable to do PCI DMA to/from anything above 1GB */
-- if (pci_dma_mapping_error(dmaaddr) ||
-- dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
-- /* This one has 30-bit addressing... */
-- if (!pci_dma_mapping_error(dmaaddr))
-- pci_unmap_single(ring->bcm->pci_dev,
-- dmaaddr, ring->rx_buffersize,
-- PCI_DMA_FROMDEVICE);
-- dev_kfree_skb_any(skb);
-- skb = __dev_alloc_skb(ring->rx_buffersize,GFP_DMA);
-- if (skb == NULL)
-- return -ENOMEM;
-- dmaaddr = pci_map_single(ring->bcm->pci_dev,
-- skb->data, ring->rx_buffersize,
-- PCI_DMA_FROMDEVICE);
-- if (pci_dma_mapping_error(dmaaddr) ||
-- dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
-- assert(0);
-- dev_kfree_skb_any(skb);
-- return -ENOMEM;
-- }
-- }
-- meta->skb = skb;
-- meta->dmaaddr = dmaaddr;
-- skb->dev = ring->bcm->net_dev;
--
-- fill_descriptor(ring, desc, dmaaddr,
-- ring->rx_buffersize, 0, 0, 0);
--
-- rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
-- rxhdr->frame_length = 0;
-- rxhdr->flags1 = 0;
-- xmitstat = (struct bcm43xx_hwxmitstatus *)(skb->data);
-- xmitstat->cookie = 0;
--
-- return 0;
--}
--
--/* Allocate the initial descbuffers.
-- * This is used for an RX ring only.
-- */
--static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
--{
-- int i, err = -ENOMEM;
-- struct bcm43xx_dmadesc_generic *desc;
-- struct bcm43xx_dmadesc_meta *meta;
--
-- for (i = 0; i < ring->nr_slots; i++) {
-- desc = bcm43xx_dma_idx2desc(ring, i, &meta);
--
-- err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
-- if (err)
-- goto err_unwind;
-- }
-- mb();
-- ring->used_slots = ring->nr_slots;
-- err = 0;
--out:
-- return err;
--
--err_unwind:
-- for (i--; i >= 0; i--) {
-- desc = bcm43xx_dma_idx2desc(ring, i, &meta);
--
-- unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
-- dev_kfree_skb(meta->skb);
-- }
-- goto out;
--}
--
--/* Do initial setup of the DMA controller.
-- * Reset the controller, write the ring busaddress
-- * and switch the "enable" bit on.
-- */
--static int dmacontroller_setup(struct bcm43xx_dmaring *ring)
--{
-- int err = 0;
-- u32 value;
-- u32 addrext;
--
-- if (ring->tx) {
-- if (ring->dma64) {
-- u64 ringbase = (u64)(ring->dmabase);
--
-- addrext = ((ringbase >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
-- value = BCM43xx_DMA64_TXENABLE;
-- value |= (addrext << BCM43xx_DMA64_TXADDREXT_SHIFT)
-- & BCM43xx_DMA64_TXADDREXT_MASK;
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL, value);
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO,
-- (ringbase & 0xFFFFFFFF));
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI,
-- ((ringbase >> 32) & ~BCM43xx_DMA64_ROUTING)
-- | ring->routing);
-- } else {
-- u32 ringbase = (u32)(ring->dmabase);
--
-- addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
-- value = BCM43xx_DMA32_TXENABLE;
-- value |= (addrext << BCM43xx_DMA32_TXADDREXT_SHIFT)
-- & BCM43xx_DMA32_TXADDREXT_MASK;
-- bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL, value);
-- bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING,
-- (ringbase & ~BCM43xx_DMA32_ROUTING)
-- | ring->routing);
-- }
-- } else {
-- err = alloc_initial_descbuffers(ring);
-- if (err)
-- goto out;
-- if (ring->dma64) {
-- u64 ringbase = (u64)(ring->dmabase);
--
-- addrext = ((ringbase >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
-- value = (ring->frameoffset << BCM43xx_DMA64_RXFROFF_SHIFT);
-- value |= BCM43xx_DMA64_RXENABLE;
-- value |= (addrext << BCM43xx_DMA64_RXADDREXT_SHIFT)
-- & BCM43xx_DMA64_RXADDREXT_MASK;
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXCTL, value);
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO,
-- (ringbase & 0xFFFFFFFF));
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI,
-- ((ringbase >> 32) & ~BCM43xx_DMA64_ROUTING)
-- | ring->routing);
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX, 200);
-- } else {
-- u32 ringbase = (u32)(ring->dmabase);
--
-- addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
-- value = (ring->frameoffset << BCM43xx_DMA32_RXFROFF_SHIFT);
-- value |= BCM43xx_DMA32_RXENABLE;
-- value |= (addrext << BCM43xx_DMA32_RXADDREXT_SHIFT)
-- & BCM43xx_DMA32_RXADDREXT_MASK;
-- bcm43xx_dma_write(ring, BCM43xx_DMA32_RXCTL, value);
-- bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING,
-- (ringbase & ~BCM43xx_DMA32_ROUTING)
-- | ring->routing);
-- bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX, 200);
-- }
-- }
--
--out:
-- return err;
--}
--
--/* Shutdown the DMA controller. */
--static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
--{
-- if (ring->tx) {
-- bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base, ring->dma64);
-- if (ring->dma64) {
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO, 0);
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI, 0);
-- } else
-- bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING, 0);
-- } else {
-- bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base, ring->dma64);
-- if (ring->dma64) {
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO, 0);
-- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI, 0);
-- } else
-- bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING, 0);
-- }
--}
--
--static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
--{
-- struct bcm43xx_dmadesc_generic *desc;
-- struct bcm43xx_dmadesc_meta *meta;
-- int i;
--
-- if (!ring->used_slots)
-- return;
-- for (i = 0; i < ring->nr_slots; i++) {
-- desc = bcm43xx_dma_idx2desc(ring, i, &meta);
--
-- if (!meta->skb) {
-- assert(ring->tx);
-- continue;
-- }
-- if (ring->tx) {
-- unmap_descbuffer(ring, meta->dmaaddr,
-- meta->skb->len, 1);
-- } else {
-- unmap_descbuffer(ring, meta->dmaaddr,
-- ring->rx_buffersize, 0);
-- }
-- free_descriptor_buffer(ring, meta, 0);
-- }
--}
--
--/* Main initialization function. */
--static
--struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
-- int controller_index,
-- int for_tx,
-- int dma64)
--{
-- struct bcm43xx_dmaring *ring;
-- int err;
-- int nr_slots;
--
-- ring = kzalloc(sizeof(*ring), GFP_KERNEL);
-- if (!ring)
-- goto out;
--
-- nr_slots = BCM43xx_RXRING_SLOTS;
-- if (for_tx)
-- nr_slots = BCM43xx_TXRING_SLOTS;
--
-- ring->meta = kcalloc(nr_slots, sizeof(struct bcm43xx_dmadesc_meta),
-- GFP_KERNEL);
-- if (!ring->meta)
-- goto err_kfree_ring;
--
-- ring->routing = BCM43xx_DMA32_CLIENTTRANS;
-- if (dma64)
-- ring->routing = BCM43xx_DMA64_CLIENTTRANS;
--
-- ring->bcm = bcm;
-- ring->nr_slots = nr_slots;
-- ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100;
-- ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100;
-- assert(ring->suspend_mark < ring->resume_mark);
-- ring->mmio_base = bcm43xx_dmacontroller_base(dma64, controller_index);
-- ring->index = controller_index;
-- ring->dma64 = !!dma64;
-- if (for_tx) {
-- ring->tx = 1;
-- ring->current_slot = -1;
-- } else {
-- if (ring->index == 0) {
-- ring->rx_buffersize = BCM43xx_DMA0_RX_BUFFERSIZE;
-- ring->frameoffset = BCM43xx_DMA0_RX_FRAMEOFFSET;
-- } else if (ring->index == 3) {
-- ring->rx_buffersize = BCM43xx_DMA3_RX_BUFFERSIZE;
-- ring->frameoffset = BCM43xx_DMA3_RX_FRAMEOFFSET;
-- } else
-- assert(0);
-- }
--
-- err = alloc_ringmemory(ring);
-- if (err)
-- goto err_kfree_meta;
-- err = dmacontroller_setup(ring);
-- if (err)
-- goto err_free_ringmemory;
-- return ring;
--
--out:
-- printk(KERN_ERR PFX "Error in bcm43xx_setup_dmaring\n");
-- return ring;
--
--err_free_ringmemory:
-- free_ringmemory(ring);
--err_kfree_meta:
-- kfree(ring->meta);
--err_kfree_ring:
-- kfree(ring);
-- ring = NULL;
-- goto out;
--}
--
--/* Main cleanup function. */
--static void bcm43xx_destroy_dmaring(struct bcm43xx_dmaring *ring)
--{
-- if (!ring)
-- return;
--
-- dprintk(KERN_INFO PFX "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
-- (ring->dma64) ? "64" : "32",
-- ring->mmio_base,
-- (ring->tx) ? "TX" : "RX",
-- ring->max_used_slots, ring->nr_slots);
-- /* Device IRQs are disabled prior entering this function,
-- * so no need to take care of concurrency with rx handler stuff.
-- */
-- dmacontroller_cleanup(ring);
-- free_all_descbuffers(ring);
-- free_ringmemory(ring);
--
-- kfree(ring->meta);
-- kfree(ring);
--}
--
--void bcm43xx_dma_free(struct bcm43xx_private *bcm)
--{
-- struct bcm43xx_dma *dma;
--
-- if (bcm43xx_using_pio(bcm))
-- return;
-- dma = bcm43xx_current_dma(bcm);
--
-- bcm43xx_destroy_dmaring(dma->rx_ring3);
-- dma->rx_ring3 = NULL;
-- bcm43xx_destroy_dmaring(dma->rx_ring0);
-- dma->rx_ring0 = NULL;
--
-- bcm43xx_destroy_dmaring(dma->tx_ring5);
-- dma->tx_ring5 = NULL;
-- bcm43xx_destroy_dmaring(dma->tx_ring4);
-- dma->tx_ring4 = NULL;
-- bcm43xx_destroy_dmaring(dma->tx_ring3);
-- dma->tx_ring3 = NULL;
-- bcm43xx_destroy_dmaring(dma->tx_ring2);
-- dma->tx_ring2 = NULL;
-- bcm43xx_destroy_dmaring(dma->tx_ring1);
-- dma->tx_ring1 = NULL;
-- bcm43xx_destroy_dmaring(dma->tx_ring0);
-- dma->tx_ring0 = NULL;
--}
--
--int bcm43xx_dma_init(struct bcm43xx_private *bcm)
--{
-- struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
-- struct bcm43xx_dmaring *ring;
-- int err = -ENOMEM;
-- int dma64 = 0;
--
-- bcm->dma_mask = bcm43xx_get_supported_dma_mask(bcm);
-- if (bcm->dma_mask == DMA_64BIT_MASK)
-- dma64 = 1;
-- err = pci_set_dma_mask(bcm->pci_dev, bcm->dma_mask);
-- if (err)
-- goto no_dma;
-- err = pci_set_consistent_dma_mask(bcm->pci_dev, bcm->dma_mask);
-- if (err)
-- goto no_dma;
--
-- /* setup TX DMA channels. */
-- ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
-- if (!ring)
-- goto out;
-- dma->tx_ring0 = ring;
--
-- ring = bcm43xx_setup_dmaring(bcm, 1, 1, dma64);
-- if (!ring)
-- goto err_destroy_tx0;
-- dma->tx_ring1 = ring;
--
-- ring = bcm43xx_setup_dmaring(bcm, 2, 1, dma64);
-- if (!ring)
-- goto err_destroy_tx1;
-- dma->tx_ring2 = ring;
--
-- ring = bcm43xx_setup_dmaring(bcm, 3, 1, dma64);
-- if (!ring)
-- goto err_destroy_tx2;
-- dma->tx_ring3 = ring;
--
-- ring = bcm43xx_setup_dmaring(bcm, 4, 1, dma64);
-- if (!ring)
-- goto err_destroy_tx3;
-- dma->tx_ring4 = ring;
--
-- ring = bcm43xx_setup_dmaring(bcm, 5, 1, dma64);
-- if (!ring)
-- goto err_destroy_tx4;
-- dma->tx_ring5 = ring;
--
-- /* setup RX DMA channels. */
-- ring = bcm43xx_setup_dmaring(bcm, 0, 0, dma64);
-- if (!ring)
-- goto err_destroy_tx5;
-- dma->rx_ring0 = ring;
--
-- if (bcm->current_core->rev < 5) {
-- ring = bcm43xx_setup_dmaring(bcm, 3, 0, dma64);
-- if (!ring)
-- goto err_destroy_rx0;
-- dma->rx_ring3 = ring;
-- }
--
-- dprintk(KERN_INFO PFX "%d-bit DMA initialized\n",
-- (bcm->dma_mask == DMA_64BIT_MASK) ? 64 :
-- (bcm->dma_mask == DMA_32BIT_MASK) ? 32 : 30);
-- err = 0;
--out:
-- return err;
--
--err_destroy_rx0:
-- bcm43xx_destroy_dmaring(dma->rx_ring0);
-- dma->rx_ring0 = NULL;
--err_destroy_tx5:
-- bcm43xx_destroy_dmaring(dma->tx_ring5);
-- dma->tx_ring5 = NULL;
--err_destroy_tx4:
-- bcm43xx_destroy_dmaring(dma->tx_ring4);
-- dma->tx_ring4 = NULL;
--err_destroy_tx3:
-- bcm43xx_destroy_dmaring(dma->tx_ring3);
-- dma->tx_ring3 = NULL;
--err_destroy_tx2:
-- bcm43xx_destroy_dmaring(dma->tx_ring2);
-- dma->tx_ring2 = NULL;
--err_destroy_tx1:
-- bcm43xx_destroy_dmaring(dma->tx_ring1);
-- dma->tx_ring1 = NULL;
--err_destroy_tx0:
-- bcm43xx_destroy_dmaring(dma->tx_ring0);
-- dma->tx_ring0 = NULL;
--no_dma:
--#ifdef CONFIG_BCM43XX_PIO
-- printk(KERN_WARNING PFX "DMA not supported on this device."
-- " Falling back to PIO.\n");
-- bcm->__using_pio = 1;
-- return -ENOSYS;
--#else
-- printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
-- "Please recompile the driver with PIO support.\n");
-- return -ENODEV;
--#endif /* CONFIG_BCM43XX_PIO */
--}
--
--/* Generate a cookie for the TX header. */
--static u16 generate_cookie(struct bcm43xx_dmaring *ring,
-- int slot)
--{
-- u16 cookie = 0x1000;
--
-- /* Use the upper 4 bits of the cookie as
-- * DMA controller ID and store the slot number
-- * in the lower 12 bits.
-- * Note that the cookie must never be 0, as this
-- * is a special value used in RX path.
-- */
-- switch (ring->index) {
-- case 0:
-- cookie = 0xA000;
-- break;
-- case 1:
-- cookie = 0xB000;
-- break;
-- case 2:
-- cookie = 0xC000;
-- break;
-- case 3:
-- cookie = 0xD000;
-- break;
-- case 4:
-- cookie = 0xE000;
-- break;
-- case 5:
-- cookie = 0xF000;
-- break;
-- }
-- assert(((u16)slot & 0xF000) == 0x0000);
-- cookie |= (u16)slot;
--
-- return cookie;
--}
--
--/* Inspect a cookie and find out to which controller/slot it belongs. */
--static
--struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
-- u16 cookie, int *slot)
--{
-- struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
-- struct bcm43xx_dmaring *ring = NULL;
--
-- switch (cookie & 0xF000) {
-- case 0xA000:
-- ring = dma->tx_ring0;
-- break;
-- case 0xB000:
-- ring = dma->tx_ring1;
-- break;
-- case 0xC000:
-- ring = dma->tx_ring2;
-- break;
-- case 0xD000:
-- ring = dma->tx_ring3;
-- break;
-- case 0xE000:
-- ring = dma->tx_ring4;
-- break;
-- case 0xF000:
-- ring = dma->tx_ring5;
-- break;
-- default:
-- assert(0);
-- }
-- *slot = (cookie & 0x0FFF);
-- assert(*slot >= 0 && *slot < ring->nr_slots);
--
-- return ring;
--}
--
--static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
-- int slot)
--{
-- u16 offset;
-- int descsize;
--
-- /* Everything is ready to start. Buffers are DMA mapped and
-- * associated with slots.
-- * "slot" is the last slot of the new frame we want to transmit.
-- * Close your seat belts now, please.
-- */
-- wmb();
-- slot = next_slot(ring, slot);
-- offset = (ring->dma64) ? BCM43xx_DMA64_TXINDEX : BCM43xx_DMA32_TXINDEX;
-- descsize = (ring->dma64) ? sizeof(struct bcm43xx_dmadesc64)
-- : sizeof(struct bcm43xx_dmadesc32);
-- bcm43xx_dma_write(ring, offset,
-- (u32)(slot * descsize));
--}
--
--static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
-- struct sk_buff *skb,
-- u8 cur_frag)
--{
-- int slot;
-- struct bcm43xx_dmadesc_generic *desc;
-- struct bcm43xx_dmadesc_meta *meta;
-- dma_addr_t dmaaddr;
-- struct sk_buff *bounce_skb;
--
-- assert(skb_shinfo(skb)->nr_frags == 0);
--
-- slot = request_slot(ring);
-- desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
--
-- /* Add a device specific TX header. */
-- assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr));
-- /* Reserve enough headroom for the device tx header. */
-- __skb_push(skb, sizeof(struct bcm43xx_txhdr));
-- /* Now calculate and add the tx header.
-- * The tx header includes the PLCP header.
-- */
-- bcm43xx_generate_txhdr(ring->bcm,
-- (struct bcm43xx_txhdr *)skb->data,
-- skb->data + sizeof(struct bcm43xx_txhdr),
-- skb->len - sizeof(struct bcm43xx_txhdr),
-- (cur_frag == 0),
-- generate_cookie(ring, slot));
-- dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
-- if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
-- /* chip cannot handle DMA to/from > 1GB, use bounce buffer (copied from b44 driver) */
-- if (!dma_mapping_error(dmaaddr))
-- unmap_descbuffer(ring, dmaaddr, skb->len, 1);
-- bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC|GFP_DMA);
-- if (!bounce_skb)
-- return;
-- dmaaddr = map_descbuffer(ring, bounce_skb->data, bounce_skb->len, 1);
-- if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
-- if (!dma_mapping_error(dmaaddr))
-- unmap_descbuffer(ring, dmaaddr, skb->len, 1);
-- dev_kfree_skb_any(bounce_skb);
-- assert(0);
-- return;
-- }
-- skb_copy_from_linear_data(skb, skb_put(bounce_skb, skb->len),
-- skb->len);
-- dev_kfree_skb_any(skb);
-- skb = bounce_skb;
-- }
--
-- meta->skb = skb;
-- meta->dmaaddr = dmaaddr;
--
-- fill_descriptor(ring, desc, dmaaddr,
-- skb->len, 1, 1, 1);
--
-- /* Now transfer the whole frame. */
-- dmacontroller_poke_tx(ring, slot);
--}
--
--int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
-- struct ieee80211_txb *txb)
--{
-- /* We just received a packet from the kernel network subsystem.
-- * Add headers and DMA map the memory. Poke
-- * the device to send the stuff.
-- * Note that this is called from atomic context.
-- */
-- struct bcm43xx_dmaring *ring = bcm43xx_current_dma(bcm)->tx_ring1;
-- u8 i;
-- struct sk_buff *skb;
--
-- assert(ring->tx);
-- if (unlikely(free_slots(ring) < txb->nr_frags)) {
-- /* The queue should be stopped,
-- * if we are low on free slots.
-- * If this ever triggers, we have to lower the suspend_mark.
-- */
-- dprintkl(KERN_ERR PFX "Out of DMA descriptor slots!\n");
-- return -ENOMEM;
-- }
--
-- for (i = 0; i < txb->nr_frags; i++) {
-- skb = txb->fragments[i];
-- /* Take skb from ieee80211_txb_free */
-- txb->fragments[i] = NULL;
-- dma_tx_fragment(ring, skb, i);
-- }
-- ieee80211_txb_free(txb);
--
-- return 0;
--}
--
--void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
-- struct bcm43xx_xmitstatus *status)
--{
-- struct bcm43xx_dmaring *ring;
-- struct bcm43xx_dmadesc_generic *desc;
-- struct bcm43xx_dmadesc_meta *meta;
-- int is_last_fragment;
-- int slot;
-- u32 tmp;
--
-- ring = parse_cookie(bcm, status->cookie, &slot);
-- assert(ring);
-- assert(ring->tx);
-- while (1) {
-- assert(slot >= 0 && slot < ring->nr_slots);
-- desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
--
-- if (ring->dma64) {
-- tmp = le32_to_cpu(desc->dma64.control0);
-- is_last_fragment = !!(tmp & BCM43xx_DMA64_DCTL0_FRAMEEND);
-- } else {
-- tmp = le32_to_cpu(desc->dma32.control);
-- is_last_fragment = !!(tmp & BCM43xx_DMA32_DCTL_FRAMEEND);
-- }
-- unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
-- free_descriptor_buffer(ring, meta, 1);
-- /* Everything belonging to the slot is unmapped
-- * and freed, so we can return it.
-- */
-- return_slot(ring, slot);
--
-- if (is_last_fragment)
-- break;
-- slot = next_slot(ring, slot);
-- }
-- bcm->stats.last_tx = jiffies;
--}
--
--static void dma_rx(struct bcm43xx_dmaring *ring,
-- int *slot)
--{
-- struct bcm43xx_dmadesc_generic *desc;
-- struct bcm43xx_dmadesc_meta *meta;
-- struct bcm43xx_rxhdr *rxhdr;
-- struct sk_buff *skb;
-- u16 len;
-- int err;
-- dma_addr_t dmaaddr;
--
-- desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
--
-- sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
-- skb = meta->skb;
--
-- if (ring->index == 3) {
-- /* We received an xmit status. */
-- struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data;
-- struct bcm43xx_xmitstatus stat;
-- int i = 0;
--
-- stat.cookie = le16_to_cpu(hw->cookie);
-- while (stat.cookie == 0) {
-- if (unlikely(++i >= 10000)) {
-- assert(0);
-- break;
-- }
-- udelay(2);
-- barrier();
-- stat.cookie = le16_to_cpu(hw->cookie);
-- }
-- stat.flags = hw->flags;
-- stat.cnt1 = hw->cnt1;
-- stat.cnt2 = hw->cnt2;
-- stat.seq = le16_to_cpu(hw->seq);
-- stat.unknown = le16_to_cpu