aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-09-08 19:10:53 -0400
committerDavid S. Miller <davem@davemloft.net>2008-09-08 19:10:53 -0400
commit9bff9dbd00e5907f5c36e72bae8aee8a46440e11 (patch)
tree4a5666939b61a13e7cde01b29baf4cb609fb8c90
parente2a6b85247aacc52d6ba0d9b37a99b8d1a3e0d83 (diff)
parentd10c4ec8b4bc02f3874c7ef3c3539e4e7e123969 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--drivers/acpi/Kconfig3
-rw-r--r--drivers/acpi/toshiba_acpi.c261
-rw-r--r--drivers/net/wireless/adm8211.c1
-rw-r--r--drivers/net/wireless/ath5k/Makefile12
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h390
-rw-r--r--drivers/net/wireless/ath5k/attach.c315
-rw-r--r--drivers/net/wireless/ath5k/base.c38
-rw-r--r--drivers/net/wireless/ath5k/caps.c193
-rw-r--r--drivers/net/wireless/ath5k/debug.c4
-rw-r--r--drivers/net/wireless/ath5k/desc.c667
-rw-r--r--drivers/net/wireless/ath5k/desc.h (renamed from drivers/net/wireless/ath5k/hw.h)400
-rw-r--r--drivers/net/wireless/ath5k/dma.c566
-rw-r--r--drivers/net/wireless/ath5k/eeprom.c466
-rw-r--r--drivers/net/wireless/ath5k/eeprom.h215
-rw-r--r--drivers/net/wireless/ath5k/gpio.c176
-rw-r--r--drivers/net/wireless/ath5k/hw.c4492
-rw-r--r--drivers/net/wireless/ath5k/initvals.c22
-rw-r--r--drivers/net/wireless/ath5k/pcu.c1002
-rw-r--r--drivers/net/wireless/ath5k/phy.c10
-rw-r--r--drivers/net/wireless/ath5k/qcu.c488
-rw-r--r--drivers/net/wireless/ath5k/reg.h102
-rw-r--r--drivers/net/wireless/ath5k/reset.c925
-rw-r--r--drivers/net/wireless/ath9k/Kconfig3
-rw-r--r--drivers/net/wireless/ath9k/main.c5
-rw-r--r--drivers/net/wireless/b43/Kconfig12
-rw-r--r--drivers/net/wireless/b43/Makefile3
-rw-r--r--drivers/net/wireless/b43/main.c69
-rw-r--r--drivers/net/wireless/b43/phy.c489
-rw-r--r--drivers/net/wireless/b43/phy_a.c130
-rw-r--r--drivers/net/wireless/b43/phy_a.h8
-rw-r--r--drivers/net/wireless/b43/phy_common.c20
-rw-r--r--drivers/net/wireless/b43/phy_common.h44
-rw-r--r--drivers/net/wireless/b43/phy_g.c104
-rw-r--r--drivers/net/wireless/b43/phy_g.h4
-rw-r--r--drivers/net/wireless/b43/phy_lp.c155
-rw-r--r--drivers/net/wireless/b43/phy_lp.h540
-rw-r--r--drivers/net/wireless/b43/phy_n.c (renamed from drivers/net/wireless/b43/nphy.c)44
-rw-r--r--drivers/net/wireless/b43/phy_n.h (renamed from drivers/net/wireless/b43/nphy.h)2
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c2
-rw-r--r--drivers/net/wireless/b43legacy/main.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-io.h24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c81
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c127
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c60
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c66
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c145
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c3
-rw-r--r--drivers/net/wireless/p54/p54.h38
-rw-r--r--drivers/net/wireless/p54/p54common.c293
-rw-r--r--drivers/net/wireless/p54/p54common.h75
-rw-r--r--drivers/net/wireless/p54/p54pci.c173
-rw-r--r--drivers/net/wireless/p54/p54usb.c180
-rw-r--r--drivers/net/wireless/p54/p54usb.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c5
-rw-r--r--drivers/net/wireless/rtl8187_dev.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c5
-rw-r--r--include/linux/nl80211.h6
-rw-r--r--include/net/wireless.h3
-rw-r--r--net/mac80211/main.c7
-rw-r--r--net/mac80211/mlme.c90
-rw-r--r--net/mac80211/rx.c4
-rw-r--r--net/mac80211/sta_info.h1
-rw-r--r--net/wireless/core.c9
-rw-r--r--net/wireless/nl80211.c22
78 files changed, 7632 insertions, 6424 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 735f5ea17473..12cf5d491f0d 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -260,6 +260,9 @@ config ACPI_ASUS
260config ACPI_TOSHIBA 260config ACPI_TOSHIBA
261 tristate "Toshiba Laptop Extras" 261 tristate "Toshiba Laptop Extras"
262 depends on X86 262 depends on X86
263 select INPUT_POLLDEV
264 select NET
265 select RFKILL
263 select BACKLIGHT_CLASS_DEVICE 266 select BACKLIGHT_CLASS_DEVICE
264 ---help--- 267 ---help---
265 This driver adds support for access to certain system settings 268 This driver adds support for access to certain system settings
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 0a43c8e0eff3..8a649f40d162 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * 4 *
5 * Copyright (C) 2002-2004 John Belmonte 5 * Copyright (C) 2002-2004 John Belmonte
6 * Copyright (C) 2008 Philip Langdale
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -33,7 +34,7 @@
33 * 34 *
34 */ 35 */
35 36
36#define TOSHIBA_ACPI_VERSION "0.18" 37#define TOSHIBA_ACPI_VERSION "0.19"
37#define PROC_INTERFACE_VERSION 1 38#define PROC_INTERFACE_VERSION 1
38 39
39#include <linux/kernel.h> 40#include <linux/kernel.h>
@@ -42,6 +43,9 @@
42#include <linux/types.h> 43#include <linux/types.h>
43#include <linux/proc_fs.h> 44#include <linux/proc_fs.h>
44#include <linux/backlight.h> 45#include <linux/backlight.h>
46#include <linux/platform_device.h>
47#include <linux/rfkill.h>
48#include <linux/input-polldev.h>
45 49
46#include <asm/uaccess.h> 50#include <asm/uaccess.h>
47 51
@@ -90,6 +94,7 @@ MODULE_LICENSE("GPL");
90#define HCI_VIDEO_OUT 0x001c 94#define HCI_VIDEO_OUT 0x001c
91#define HCI_HOTKEY_EVENT 0x001e 95#define HCI_HOTKEY_EVENT 0x001e
92#define HCI_LCD_BRIGHTNESS 0x002a 96#define HCI_LCD_BRIGHTNESS 0x002a
97#define HCI_WIRELESS 0x0056
93 98
94/* field definitions */ 99/* field definitions */
95#define HCI_LCD_BRIGHTNESS_BITS 3 100#define HCI_LCD_BRIGHTNESS_BITS 3
@@ -98,9 +103,14 @@ MODULE_LICENSE("GPL");
98#define HCI_VIDEO_OUT_LCD 0x1 103#define HCI_VIDEO_OUT_LCD 0x1
99#define HCI_VIDEO_OUT_CRT 0x2 104#define HCI_VIDEO_OUT_CRT 0x2
100#define HCI_VIDEO_OUT_TV 0x4 105#define HCI_VIDEO_OUT_TV 0x4
106#define HCI_WIRELESS_KILL_SWITCH 0x01
107#define HCI_WIRELESS_BT_PRESENT 0x0f
108#define HCI_WIRELESS_BT_ATTACH 0x40
109#define HCI_WIRELESS_BT_POWER 0x80
101 110
102static const struct acpi_device_id toshiba_device_ids[] = { 111static const struct acpi_device_id toshiba_device_ids[] = {
103 {"TOS6200", 0}, 112 {"TOS6200", 0},
113 {"TOS6208", 0},
104 {"TOS1900", 0}, 114 {"TOS1900", 0},
105 {"", 0}, 115 {"", 0},
106}; 116};
@@ -193,7 +203,7 @@ static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
193 return status; 203 return status;
194} 204}
195 205
196/* common hci tasks (get or set one value) 206/* common hci tasks (get or set one or two value)
197 * 207 *
198 * In addition to the ACPI status, the HCI system returns a result which 208 * In addition to the ACPI status, the HCI system returns a result which
199 * may be useful (such as "not supported"). 209 * may be useful (such as "not supported").
@@ -218,6 +228,152 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result)
218 return status; 228 return status;
219} 229}
220 230
231static acpi_status hci_write2(u32 reg, u32 in1, u32 in2, u32 *result)
232{
233 u32 in[HCI_WORDS] = { HCI_SET, reg, in1, in2, 0, 0 };
234 u32 out[HCI_WORDS];
235 acpi_status status = hci_raw(in, out);
236 *result = (status == AE_OK) ? out[0] : HCI_FAILURE;
237 return status;
238}
239
240static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
241{
242 u32 in[HCI_WORDS] = { HCI_GET, reg, *out1, *out2, 0, 0 };
243 u32 out[HCI_WORDS];
244 acpi_status status = hci_raw(in, out);
245 *out1 = out[2];
246 *out2 = out[3];
247 *result = (status == AE_OK) ? out[0] : HCI_FAILURE;
248 return status;
249}
250
251struct toshiba_acpi_dev {
252 struct platform_device *p_dev;
253 struct rfkill *rfk_dev;
254 struct input_polled_dev *poll_dev;
255
256 const char *bt_name;
257 const char *rfk_name;
258
259 bool last_rfk_state;
260
261 struct mutex mutex;
262};
263
264static struct toshiba_acpi_dev toshiba_acpi = {
265 .bt_name = "Toshiba Bluetooth",
266 .rfk_name = "Toshiba RFKill Switch",
267 .last_rfk_state = false,
268};
269
270/* Bluetooth rfkill handlers */
271
272static u32 hci_get_bt_present(bool *present)
273{
274 u32 hci_result;
275 u32 value, value2;
276
277 value = 0;
278 value2 = 0;
279 hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
280 if (hci_result == HCI_SUCCESS)
281 *present = (value & HCI_WIRELESS_BT_PRESENT) ? true : false;
282
283 return hci_result;
284}
285
286static u32 hci_get_bt_on(bool *on)
287{
288 u32 hci_result;
289 u32 value, value2;
290
291 value = 0;
292 value2 = 0x0001;
293 hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
294 if (hci_result == HCI_SUCCESS)
295 *on = (value & HCI_WIRELESS_BT_POWER) &&
296 (value & HCI_WIRELESS_BT_ATTACH);
297
298 return hci_result;
299}
300
301static u32 hci_get_radio_state(bool *radio_state)
302{
303 u32 hci_result;
304 u32 value, value2;
305
306 value = 0;
307 value2 = 0x0001;
308 hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
309
310 *radio_state = value & HCI_WIRELESS_KILL_SWITCH;
311 return hci_result;
312}
313
314static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state)
315{
316 u32 result1, result2;
317 u32 value;
318 bool radio_state;
319 struct toshiba_acpi_dev *dev = data;
320
321 value = (state == RFKILL_STATE_UNBLOCKED);
322
323 if (hci_get_radio_state(&radio_state) != HCI_SUCCESS)
324 return -EFAULT;
325
326 switch (state) {
327 case RFKILL_STATE_UNBLOCKED:
328 if (!radio_state)
329 return -EPERM;
330 break;
331 case RFKILL_STATE_SOFT_BLOCKED:
332 break;
333 default:
334 return -EINVAL;
335 }
336
337 mutex_lock(&dev->mutex);
338 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1);
339 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2);
340 mutex_unlock(&dev->mutex);
341
342 if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS)
343 return -EFAULT;
344
345 return 0;
346}
347
348static void bt_poll_rfkill(struct input_polled_dev *poll_dev)
349{
350 bool state_changed;
351 bool new_rfk_state;
352 bool value;
353 u32 hci_result;
354 struct toshiba_acpi_dev *dev = poll_dev->private;
355
356 hci_result = hci_get_radio_state(&value);
357 if (hci_result != HCI_SUCCESS)
358 return; /* Can't do anything useful */
359
360 new_rfk_state = value;
361
362 mutex_lock(&dev->mutex);
363 state_changed = new_rfk_state != dev->last_rfk_state;
364 dev->last_rfk_state = new_rfk_state;
365 mutex_unlock(&dev->mutex);
366
367 if (unlikely(state_changed)) {
368 rfkill_force_state(dev->rfk_dev,
369 new_rfk_state ?
370 RFKILL_STATE_SOFT_BLOCKED :
371 RFKILL_STATE_HARD_BLOCKED);
372 input_report_switch(poll_dev->input, SW_RFKILL_ALL,
373 new_rfk_state);
374 }
375}
376
221static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; 377static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
222static struct backlight_device *toshiba_backlight_device; 378static struct backlight_device *toshiba_backlight_device;
223static int force_fan; 379static int force_fan;
@@ -547,6 +703,14 @@ static struct backlight_ops toshiba_backlight_data = {
547 703
548static void toshiba_acpi_exit(void) 704static void toshiba_acpi_exit(void)
549{ 705{
706 if (toshiba_acpi.poll_dev) {
707 input_unregister_polled_device(toshiba_acpi.poll_dev);
708 input_free_polled_device(toshiba_acpi.poll_dev);
709 }
710
711 if (toshiba_acpi.rfk_dev)
712 rfkill_unregister(toshiba_acpi.rfk_dev);
713
550 if (toshiba_backlight_device) 714 if (toshiba_backlight_device)
551 backlight_device_unregister(toshiba_backlight_device); 715 backlight_device_unregister(toshiba_backlight_device);
552 716
@@ -555,6 +719,8 @@ static void toshiba_acpi_exit(void)
555 if (toshiba_proc_dir) 719 if (toshiba_proc_dir)
556 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); 720 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
557 721
722 platform_device_unregister(toshiba_acpi.p_dev);
723
558 return; 724 return;
559} 725}
560 726
@@ -562,6 +728,10 @@ static int __init toshiba_acpi_init(void)
562{ 728{
563 acpi_status status = AE_OK; 729 acpi_status status = AE_OK;
564 u32 hci_result; 730 u32 hci_result;
731 bool bt_present;
732 bool bt_on;
733 bool radio_on;
734 int ret = 0;
565 735
566 if (acpi_disabled) 736 if (acpi_disabled)
567 return -ENODEV; 737 return -ENODEV;
@@ -578,6 +748,18 @@ static int __init toshiba_acpi_init(void)
578 TOSHIBA_ACPI_VERSION); 748 TOSHIBA_ACPI_VERSION);
579 printk(MY_INFO " HCI method: %s\n", method_hci); 749 printk(MY_INFO " HCI method: %s\n", method_hci);
580 750
751 mutex_init(&toshiba_acpi.mutex);
752
753 toshiba_acpi.p_dev = platform_device_register_simple("toshiba_acpi",
754 -1, NULL, 0);
755 if (IS_ERR(toshiba_acpi.p_dev)) {
756 ret = PTR_ERR(toshiba_acpi.p_dev);
757 printk(MY_ERR "unable to register platform device\n");
758 toshiba_acpi.p_dev = NULL;
759 toshiba_acpi_exit();
760 return ret;
761 }
762
581 force_fan = 0; 763 force_fan = 0;
582 key_event_valid = 0; 764 key_event_valid = 0;
583 765
@@ -586,19 +768,23 @@ static int __init toshiba_acpi_init(void)
586 768
587 toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); 769 toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir);
588 if (!toshiba_proc_dir) { 770 if (!toshiba_proc_dir) {
589 status = AE_ERROR; 771 toshiba_acpi_exit();
772 return -ENODEV;
590 } else { 773 } else {
591 toshiba_proc_dir->owner = THIS_MODULE; 774 toshiba_proc_dir->owner = THIS_MODULE;
592 status = add_device(); 775 status = add_device();
593 if (ACPI_FAILURE(status)) 776 if (ACPI_FAILURE(status)) {
594 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); 777 toshiba_acpi_exit();
778 return -ENODEV;
779 }
595 } 780 }
596 781
597 toshiba_backlight_device = backlight_device_register("toshiba",NULL, 782 toshiba_backlight_device = backlight_device_register("toshiba",
783 &toshiba_acpi.p_dev->dev,
598 NULL, 784 NULL,
599 &toshiba_backlight_data); 785 &toshiba_backlight_data);
600 if (IS_ERR(toshiba_backlight_device)) { 786 if (IS_ERR(toshiba_backlight_device)) {
601 int ret = PTR_ERR(toshiba_backlight_device); 787 ret = PTR_ERR(toshiba_backlight_device);
602 788
603 printk(KERN_ERR "Could not register toshiba backlight device\n"); 789 printk(KERN_ERR "Could not register toshiba backlight device\n");
604 toshiba_backlight_device = NULL; 790 toshiba_backlight_device = NULL;
@@ -607,7 +793,66 @@ static int __init toshiba_acpi_init(void)
607 } 793 }
608 toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; 794 toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
609 795
610 return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; 796 /* Register rfkill switch for Bluetooth */
797 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
798 toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev,
799 RFKILL_TYPE_BLUETOOTH);
800 if (!toshiba_acpi.rfk_dev) {
801 printk(MY_ERR "unable to allocate rfkill device\n");
802 toshiba_acpi_exit();
803 return -ENOMEM;
804 }
805
806 toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name;
807 toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio;
808 toshiba_acpi.rfk_dev->user_claim_unsupported = 1;
809 toshiba_acpi.rfk_dev->data = &toshiba_acpi;
810
811 if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) {
812 toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED;
813 } else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS &&
814 radio_on) {
815 toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED;
816 } else {
817 toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED;
818 }
819
820 ret = rfkill_register(toshiba_acpi.rfk_dev);
821 if (ret) {
822 printk(MY_ERR "unable to register rfkill device\n");
823 toshiba_acpi_exit();
824 return -ENOMEM;
825 }
826 }
827
828 /* Register input device for kill switch */
829 toshiba_acpi.poll_dev = input_allocate_polled_device();
830 if (!toshiba_acpi.poll_dev) {
831 printk(MY_ERR "unable to allocate kill-switch input device\n");
832 toshiba_acpi_exit();
833 return -ENOMEM;
834 }
835 toshiba_acpi.poll_dev->private = &toshiba_acpi;
836 toshiba_acpi.poll_dev->poll = bt_poll_rfkill;
837 toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */
838
839 toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name;
840 toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST;
841 toshiba_acpi.poll_dev->input->id.vendor = 0x0930; /* Toshiba USB ID */
842 set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
843 set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
844 input_report_switch(toshiba_acpi.poll_dev->input, SW_RFKILL_ALL, TRUE);
845
846 ret = input_register_polled_device(toshiba_acpi.poll_dev);
847 if (ret) {
848 printk(MY_ERR "unable to register kill-switch input device\n");
849 rfkill_free(toshiba_acpi.rfk_dev);
850 toshiba_acpi.rfk_dev = NULL;
851 toshiba_acpi_exit();
852 return ret;
853 }
854
855 return 0;
611} 856}
612 857
613module_init(toshiba_acpi_init); 858module_init(toshiba_acpi_init);
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 3333d4596b8d..c6a55cd12db9 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1884,6 +1884,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
1884 dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); 1884 dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
1885 /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ 1885 /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
1886 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; 1886 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
1887 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1887 1888
1888 dev->channel_change_time = 1000; 1889 dev->channel_change_time = 1000;
1889 dev->max_signal = 100; /* FIXME: find better value */ 1890 dev->max_signal = 100; /* FIXME: find better value */
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile
index 564ecd0c5d4b..719cfaef7085 100644
--- a/drivers/net/wireless/ath5k/Makefile
+++ b/drivers/net/wireless/ath5k/Makefile
@@ -1,6 +1,14 @@
1ath5k-y += base.o 1ath5k-y += caps.o
2ath5k-y += hw.o
3ath5k-y += initvals.o 2ath5k-y += initvals.o
3ath5k-y += eeprom.o
4ath5k-y += gpio.o
5ath5k-y += desc.o
6ath5k-y += dma.o
7ath5k-y += qcu.o
8ath5k-y += pcu.o
4ath5k-y += phy.o 9ath5k-y += phy.o
10ath5k-y += reset.o
11ath5k-y += attach.o
12ath5k-y += base.o
5ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o 13ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
6obj-$(CONFIG_ATH5K) += ath5k.o 14obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index c1b497873668..4c0211798a7a 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -18,18 +18,23 @@
18#ifndef _ATH5K_H 18#ifndef _ATH5K_H
19#define _ATH5K_H 19#define _ATH5K_H
20 20
21/* Set this to 1 to disable regulatory domain restrictions for channel tests. 21/* TODO: Clean up channel debuging -doesn't work anyway- and start
22 * WARNING: This is for debuging only and has side effects (eg. scan takes too 22 * working on reg. control code using all available eeprom information
23 * long and results timeouts). It's also illegal to tune to some of the 23 * -rev. engineering needed- */
24 * supported frequencies in some countries, so use this at your own risk,
25 * you've been warned. */
26#define CHAN_DEBUG 0 24#define CHAN_DEBUG 0
27 25
28#include <linux/io.h> 26#include <linux/io.h>
29#include <linux/types.h> 27#include <linux/types.h>
30#include <net/mac80211.h> 28#include <net/mac80211.h>
31 29
32#include "hw.h" 30/* RX/TX descriptor hw structs
31 * TODO: Driver part should only see sw structs */
32#include "desc.h"
33
34/* EEPROM structs/offsets
35 * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
36 * and clean up common bits, then introduce set/get functions in eeprom.c */
37#include "eeprom.h"
33 38
34/* PCI IDs */ 39/* PCI IDs */
35#define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ 40#define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */
@@ -87,7 +92,92 @@
87 ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__) 92 ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__)
88 93
89/* 94/*
95 * AR5K REGISTER ACCESS
96 */
97
98/* Some macros to read/write fields */
99
100/* First shift, then mask */
101#define AR5K_REG_SM(_val, _flags) \
102 (((_val) << _flags##_S) & (_flags))
103
104/* First mask, then shift */
105#define AR5K_REG_MS(_val, _flags) \
106 (((_val) & (_flags)) >> _flags##_S)
107
108/* Some registers can hold multiple values of interest. For this
109 * reason when we want to write to these registers we must first
110 * retrieve the values which we do not want to clear (lets call this
111 * old_data) and then set the register with this and our new_value:
112 * ( old_data | new_value) */
113#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val) \
114 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \
115 (((_val) << _flags##_S) & (_flags)), _reg)
116
117#define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask) \
118 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & \
119 (_mask)) | (_flags), _reg)
120
121#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags) \
122 ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg)
123
124#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \
125 ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg)
126
127/* Access to PHY registers */
128#define AR5K_PHY_READ(ah, _reg) \
129 ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
130
131#define AR5K_PHY_WRITE(ah, _reg, _val) \
132 ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
133
134/* Access QCU registers per queue */
135#define AR5K_REG_READ_Q(ah, _reg, _queue) \
136 (ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \
137
138#define AR5K_REG_WRITE_Q(ah, _reg, _queue) \
139 ath5k_hw_reg_write(ah, (1 << _queue), _reg)
140
141#define AR5K_Q_ENABLE_BITS(_reg, _queue) do { \
142 _reg |= 1 << _queue; \
143} while (0)
144
145#define AR5K_Q_DISABLE_BITS(_reg, _queue) do { \
146 _reg &= ~(1 << _queue); \
147} while (0)
148
149/* Used while writing initvals */
150#define AR5K_REG_WAIT(_i) do { \
151 if (_i % 64) \
152 udelay(1); \
153} while (0)
154
155/* Register dumps are done per operation mode */
156#define AR5K_INI_RFGAIN_5GHZ 0
157#define AR5K_INI_RFGAIN_2GHZ 1
158
159/* TODO: Clean this up */
160#define AR5K_INI_VAL_11A 0
161#define AR5K_INI_VAL_11A_TURBO 1
162#define AR5K_INI_VAL_11B 2
163#define AR5K_INI_VAL_11G 3
164#define AR5K_INI_VAL_11G_TURBO 4
165#define AR5K_INI_VAL_XR 0
166#define AR5K_INI_VAL_MAX 5
167
168#define AR5K_RF5111_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
169#define AR5K_RF5112_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
170
171/* Used for BSSID etc manipulation */
172#define AR5K_LOW_ID(_a)( \
173(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
174)
175
176#define AR5K_HIGH_ID(_a) ((_a)[4] | (_a)[5] << 8)
177
178/*
90 * Some tuneable values (these should be changeable by the user) 179 * Some tuneable values (these should be changeable by the user)
180 * TODO: Make use of them and add more options OR use debug/configfs
91 */ 181 */
92#define AR5K_TUNE_DMA_BEACON_RESP 2 182#define AR5K_TUNE_DMA_BEACON_RESP 2
93#define AR5K_TUNE_SW_BEACON_RESP 10 183#define AR5K_TUNE_SW_BEACON_RESP 10
@@ -98,13 +188,13 @@
98#define AR5K_TUNE_REGISTER_TIMEOUT 20000 188#define AR5K_TUNE_REGISTER_TIMEOUT 20000
99/* Register for RSSI threshold has a mask of 0xff, so 255 seems to 189/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
100 * be the max value. */ 190 * be the max value. */
101#define AR5K_TUNE_RSSI_THRES 129 191#define AR5K_TUNE_RSSI_THRES 129
102/* This must be set when setting the RSSI threshold otherwise it can 192/* This must be set when setting the RSSI threshold otherwise it can
103 * prevent a reset. If AR5K_RSSI_THR is read after writing to it 193 * prevent a reset. If AR5K_RSSI_THR is read after writing to it
104 * the BMISS_THRES will be seen as 0, seems harware doesn't keep 194 * the BMISS_THRES will be seen as 0, seems harware doesn't keep
105 * track of it. Max value depends on harware. For AR5210 this is just 7. 195 * track of it. Max value depends on harware. For AR5210 this is just 7.
106 * For AR5211+ this seems to be up to 255. */ 196 * For AR5211+ this seems to be up to 255. */
107#define AR5K_TUNE_BMISS_THRES 7 197#define AR5K_TUNE_BMISS_THRES 7
108#define AR5K_TUNE_REGISTER_DWELL_TIME 20000 198#define AR5K_TUNE_REGISTER_DWELL_TIME 20000
109#define AR5K_TUNE_BEACON_INTERVAL 100 199#define AR5K_TUNE_BEACON_INTERVAL 100
110#define AR5K_TUNE_AIFS 2 200#define AR5K_TUNE_AIFS 2
@@ -123,6 +213,55 @@
123#define AR5K_TUNE_ANT_DIVERSITY true 213#define AR5K_TUNE_ANT_DIVERSITY true
124#define AR5K_TUNE_HWTXTRIES 4 214#define AR5K_TUNE_HWTXTRIES 4
125 215
216#define AR5K_INIT_CARR_SENSE_EN 1
217
218/*Swap RX/TX Descriptor for big endian archs*/
219#if defined(__BIG_ENDIAN)
220#define AR5K_INIT_CFG ( \
221 AR5K_CFG_SWTD | AR5K_CFG_SWRD \
222)
223#else
224#define AR5K_INIT_CFG 0x00000000
225#endif
226
227/* Initial values */
228#define AR5K_INIT_TX_LATENCY 502
229#define AR5K_INIT_USEC 39
230#define AR5K_INIT_USEC_TURBO 79
231#define AR5K_INIT_USEC_32 31
232#define AR5K_INIT_SLOT_TIME 396
233#define AR5K_INIT_SLOT_TIME_TURBO 480
234#define AR5K_INIT_ACK_CTS_TIMEOUT 1024
235#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800
236#define AR5K_INIT_PROG_IFS 920
237#define AR5K_INIT_PROG_IFS_TURBO 960
238#define AR5K_INIT_EIFS 3440
239#define AR5K_INIT_EIFS_TURBO 6880
240#define AR5K_INIT_SIFS 560
241#define AR5K_INIT_SIFS_TURBO 480
242#define AR5K_INIT_SH_RETRY 10
243#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY
244#define AR5K_INIT_SSH_RETRY 32
245#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY
246#define AR5K_INIT_TX_RETRY 10
247
248#define AR5K_INIT_TRANSMIT_LATENCY ( \
249 (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
250 (AR5K_INIT_USEC) \
251)
252#define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \
253 (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
254 (AR5K_INIT_USEC_TURBO) \
255)
256#define AR5K_INIT_PROTO_TIME_CNTRL ( \
257 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \
258 (AR5K_INIT_PROG_IFS) \
259)
260#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \
261 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
262 (AR5K_INIT_PROG_IFS_TURBO) \
263)
264
126/* token to use for aifs, cwmin, cwmax in MadWiFi */ 265/* token to use for aifs, cwmin, cwmax in MadWiFi */
127#define AR5K_TXQ_USEDEFAULT ((u32) -1) 266#define AR5K_TXQ_USEDEFAULT ((u32) -1)
128 267
@@ -196,7 +335,6 @@ struct ath5k_srev_name {
196#define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */ 335#define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */
197 336
198/* IEEE defs */ 337/* IEEE defs */
199
200#define IEEE80211_MAX_LEN 2500 338#define IEEE80211_MAX_LEN 2500
201 339
202/* TODO add support to mac80211 for vendor-specific rates and modes */ 340/* TODO add support to mac80211 for vendor-specific rates and modes */
@@ -268,16 +406,13 @@ enum ath5k_driver_mode {
268 AR5K_MODE_MAX = 5 406 AR5K_MODE_MAX = 5
269}; 407};
270 408
271/* adding this flag to rate_code enables short preamble, see ar5212_reg.h */
272#define AR5K_SET_SHORT_PREAMBLE 0x04
273
274 409
275/****************\ 410/****************\
276 TX DEFINITIONS 411 TX DEFINITIONS
277\****************/ 412\****************/
278 413
279/* 414/*
280 * TX Status 415 * TX Status descriptor
281 */ 416 */
282struct ath5k_tx_status { 417struct ath5k_tx_status {
283 u16 ts_seqnum; 418 u16 ts_seqnum;
@@ -349,7 +484,6 @@ enum ath5k_tx_queue_id {
349 AR5K_TX_QUEUE_ID_XR_DATA = 9, 484 AR5K_TX_QUEUE_ID_XR_DATA = 9,
350}; 485};
351 486
352
353/* 487/*
354 * Flags to set hw queue's parameters... 488 * Flags to set hw queue's parameters...
355 */ 489 */
@@ -382,7 +516,8 @@ struct ath5k_txq_info {
382 516
383/* 517/*
384 * Transmit packet types. 518 * Transmit packet types.
385 * These are not fully used inside OpenHAL yet 519 * used on tx control descriptor
520 * TODO: Use them inside base.c corectly
386 */ 521 */
387enum ath5k_pkt_type { 522enum ath5k_pkt_type {
388 AR5K_PKT_TYPE_NORMAL = 0, 523 AR5K_PKT_TYPE_NORMAL = 0,
@@ -425,7 +560,7 @@ enum ath5k_dmasize {
425\****************/ 560\****************/
426 561
427/* 562/*
428 * RX Status 563 * RX Status descriptor
429 */ 564 */
430struct ath5k_rx_status { 565struct ath5k_rx_status {
431 u16 rs_datalen; 566 u16 rs_datalen;
@@ -489,34 +624,59 @@ struct ath5k_beacon_state {
489#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10) 624#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10)
490 625
491 626
627/*******************************\
628 GAIN OPTIMIZATION DEFINITIONS
629\*******************************/
630
631enum ath5k_rfgain {
632 AR5K_RFGAIN_INACTIVE = 0,
633 AR5K_RFGAIN_READ_REQUESTED,
634 AR5K_RFGAIN_NEED_CHANGE,
635};
636
637#define AR5K_GAIN_CRN_FIX_BITS_5111 4
638#define AR5K_GAIN_CRN_FIX_BITS_5112 7
639#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112
640#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15
641#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20
642#define AR5K_GAIN_CCK_PROBE_CORR 5
643#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15
644#define AR5K_GAIN_STEP_COUNT 10
645#define AR5K_GAIN_PARAM_TX_CLIP 0
646#define AR5K_GAIN_PARAM_PD_90 1
647#define AR5K_GAIN_PARAM_PD_84 2
648#define AR5K_GAIN_PARAM_GAIN_SEL 3
649#define AR5K_GAIN_PARAM_MIX_ORN 0
650#define AR5K_GAIN_PARAM_PD_138 1
651#define AR5K_GAIN_PARAM_PD_137 2
652#define AR5K_GAIN_PARAM_PD_136 3
653#define AR5K_GAIN_PARAM_PD_132 4
654#define AR5K_GAIN_PARAM_PD_131 5
655#define AR5K_GAIN_PARAM_PD_130 6
656#define AR5K_GAIN_CHECK_ADJUST(_g) \
657 ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
658
659struct ath5k_gain_opt_step {
660 s16 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
661 s32 gos_gain;
662};
663
664struct ath5k_gain {
665 u32 g_step_idx;
666 u32 g_current;
667 u32 g_target;
668 u32 g_low;
669 u32 g_high;
670 u32 g_f_corr;
671 u32 g_active;
672 const struct ath5k_gain_opt_step *g_step;
673};
674
675
492/********************\ 676/********************\
493 COMMON DEFINITIONS 677 COMMON DEFINITIONS
494\********************/ 678\********************/
495 679
496/*
497 * Atheros hardware descriptor
498 * This is read and written to by the hardware
499 */
500struct ath5k_desc {
501 u32 ds_link; /* physical address of the next descriptor */
502 u32 ds_data; /* physical address of data buffer (skb) */
503
504 union {
505 struct ath5k_hw_5210_tx_desc ds_tx5210;
506 struct ath5k_hw_5212_tx_desc ds_tx5212;
507 struct ath5k_hw_all_rx_desc ds_rx;
508 } ud;
509} __packed;
510
511#define AR5K_RXDESC_INTREQ 0x0020
512
513#define AR5K_TXDESC_CLRDMASK 0x0001
514#define AR5K_TXDESC_NOACK 0x0002 /*[5211+]*/
515#define AR5K_TXDESC_RTSENA 0x0004
516#define AR5K_TXDESC_CTSENA 0x0008
517#define AR5K_TXDESC_INTREQ 0x0010
518#define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/
519
520#define AR5K_SLOT_TIME_9 396 680#define AR5K_SLOT_TIME_9 396
521#define AR5K_SLOT_TIME_20 880 681#define AR5K_SLOT_TIME_20 880
522#define AR5K_SLOT_TIME_MAX 0xffff 682#define AR5K_SLOT_TIME_MAX 0xffff
@@ -548,15 +708,16 @@ struct ath5k_desc {
548#define CHANNEL_MODES CHANNEL_ALL 708#define CHANNEL_MODES CHANNEL_ALL
549 709
550/* 710/*
551 * Used internaly in OpenHAL (ar5211.c/ar5212.c 711 * Used internaly for reset_tx_queue).
552 * for reset_tx_queue). Also see struct struct ieee80211_channel. 712 * Also see struct struct ieee80211_channel.
553 */ 713 */
554#define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0) 714#define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0)
555#define IS_CHAN_B(_c) ((_c.hw_value & CHANNEL_B) != 0) 715#define IS_CHAN_B(_c) ((_c.hw_value & CHANNEL_B) != 0)
556 716
557/* 717/*
558 * The following structure will be used to map 2GHz channels to 718 * The following structure is used to map 2GHz channels to
559 * 5GHz Atheros channels. 719 * 5GHz Atheros channels.
720 * TODO: Clean up
560 */ 721 */
561struct ath5k_athchan_2ghz { 722struct ath5k_athchan_2ghz {
562 u32 a2_flags; 723 u32 a2_flags;
@@ -564,9 +725,9 @@ struct ath5k_athchan_2ghz {
564}; 725};
565 726
566 727
567/* 728/******************\
568 * Rate definitions 729 RATE DEFINITIONS
569 */ 730\******************/
570 731
571/** 732/**
572 * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32. 733 * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32.
@@ -618,6 +779,8 @@ struct ath5k_athchan_2ghz {
618#define ATH5K_RATE_CODE_XR_2M 0x06 779#define ATH5K_RATE_CODE_XR_2M 0x06
619#define ATH5K_RATE_CODE_XR_3M 0x01 780#define ATH5K_RATE_CODE_XR_3M 0x01
620 781
782/* adding this flag to rate_code enables short preamble */
783#define AR5K_SET_SHORT_PREAMBLE 0x04
621 784
622/* 785/*
623 * Crypto definitions 786 * Crypto definitions
@@ -639,7 +802,6 @@ struct ath5k_athchan_2ghz {
639 return (false); \ 802 return (false); \
640} while (0) 803} while (0)
641 804
642
643enum ath5k_ant_setting { 805enum ath5k_ant_setting {
644 AR5K_ANT_VARIABLE = 0, /* variable by programming */ 806 AR5K_ANT_VARIABLE = 0, /* variable by programming */
645 AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */ 807 AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */
@@ -750,7 +912,8 @@ enum ath5k_power_mode {
750 912
751/* 913/*
752 * These match net80211 definitions (not used in 914 * These match net80211 definitions (not used in
753 * d80211). 915 * mac80211).
916 * TODO: Clean this up
754 */ 917 */
755#define AR5K_LED_INIT 0 /*IEEE80211_S_INIT*/ 918#define AR5K_LED_INIT 0 /*IEEE80211_S_INIT*/
756#define AR5K_LED_SCAN 1 /*IEEE80211_S_SCAN*/ 919#define AR5K_LED_SCAN 1 /*IEEE80211_S_SCAN*/
@@ -766,7 +929,8 @@ enum ath5k_power_mode {
766/* 929/*
767 * Chipset capabilities -see ath5k_hw_get_capability- 930 * Chipset capabilities -see ath5k_hw_get_capability-
768 * get_capability function is not yet fully implemented 931 * get_capability function is not yet fully implemented
769 * in OpenHAL so most of these don't work yet... 932 * in ath5k so most of these don't work yet...
933 * TODO: Implement these & merge with _TUNE_ stuff above
770 */ 934 */
771enum ath5k_capability_type { 935enum ath5k_capability_type {
772 AR5K_CAP_REG_DMN = 0, /* Used to get current reg. domain id */ 936 AR5K_CAP_REG_DMN = 0, /* Used to get current reg. domain id */
@@ -835,6 +999,7 @@ struct ath5k_capabilities {
835#define AR5K_MAX_GPIO 10 999#define AR5K_MAX_GPIO 10
836#define AR5K_MAX_RF_BANKS 8 1000#define AR5K_MAX_RF_BANKS 8
837 1001
1002/* TODO: Clean up and merge with ath5k_softc */
838struct ath5k_hw { 1003struct ath5k_hw {
839 u32 ah_magic; 1004 u32 ah_magic;
840 1005
@@ -927,11 +1092,13 @@ struct ath5k_hw {
927 /* 1092 /*
928 * Function pointers 1093 * Function pointers
929 */ 1094 */
1095 int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc,
1096 u32 size, unsigned int flags);
930 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1097 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
931 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, 1098 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
932 unsigned int, unsigned int, unsigned int, unsigned int, 1099 unsigned int, unsigned int, unsigned int, unsigned int,
933 unsigned int, unsigned int, unsigned int); 1100 unsigned int, unsigned int, unsigned int);
934 int (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1101 int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
935 unsigned int, unsigned int, unsigned int, unsigned int, 1102 unsigned int, unsigned int, unsigned int, unsigned int,
936 unsigned int, unsigned int); 1103 unsigned int, unsigned int);
937 int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1104 int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
@@ -944,33 +1111,38 @@ struct ath5k_hw {
944 * Prototypes 1111 * Prototypes
945 */ 1112 */
946 1113
947/* General Functions */
948extern int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, bool is_set);
949/* Attach/Detach Functions */ 1114/* Attach/Detach Functions */
950extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version); 1115extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
951extern const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, unsigned int mode);
952extern void ath5k_hw_detach(struct ath5k_hw *ah); 1116extern void ath5k_hw_detach(struct ath5k_hw *ah);
1117
953/* Reset Functions */ 1118/* Reset Functions */
1119extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
954extern int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, struct ieee80211_channel *channel, bool change_channel); 1120extern int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, struct ieee80211_channel *channel, bool change_channel);
955/* Power management functions */ 1121/* Power management functions */
956extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration); 1122extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
1123
957/* DMA Related Functions */ 1124/* DMA Related Functions */
958extern void ath5k_hw_start_rx(struct ath5k_hw *ah); 1125extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
959extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); 1126extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
960extern u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah); 1127extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
961extern void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr); 1128extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
962extern int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue); 1129extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
963extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1130extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
964extern u32 ath5k_hw_get_tx_buf(struct ath5k_hw *ah, unsigned int queue); 1131extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
965extern int ath5k_hw_put_tx_buf(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr); 1132extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
1133 u32 phys_addr);
966extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); 1134extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
967/* Interrupt handling */ 1135/* Interrupt handling */
968extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); 1136extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
969extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); 1137extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
970extern enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask); 1138extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum
1139ath5k_int new_mask);
971extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats); 1140extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats);
1141
972/* EEPROM access functions */ 1142/* EEPROM access functions */
973extern int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain); 1143extern int ath5k_eeprom_init(struct ath5k_hw *ah);
1144extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1145
974/* Protocol Control Unit Functions */ 1146/* Protocol Control Unit Functions */
975extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1147extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
976/* BSSID Functions */ 1148/* BSSID Functions */
@@ -980,14 +1152,14 @@ extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc
980extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); 1152extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
981/* Receive start/stop functions */ 1153/* Receive start/stop functions */
982extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); 1154extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
983extern void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah); 1155extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
984/* RX Filter functions */ 1156/* RX Filter functions */
985extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); 1157extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
986extern int ath5k_hw_set_mcast_filterindex(struct ath5k_hw *ah, u32 index); 1158extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
987extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index); 1159extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
988extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); 1160extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
989extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); 1161extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
990/* Beacon related functions */ 1162/* Beacon control functions */
991extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); 1163extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
992extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); 1164extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
993extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); 1165extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
@@ -1009,61 +1181,129 @@ extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1009extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); 1181extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
1010extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac); 1182extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac);
1011extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); 1183extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
1184
1012/* Queue Control Unit, DFS Control Unit Functions */ 1185/* Queue Control Unit, DFS Control Unit Functions */
1013extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, struct ath5k_txq_info *queue_info);
1014extern int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue, const struct ath5k_txq_info *queue_info);
1015extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info); 1186extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info);
1187extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
1188 const struct ath5k_txq_info *queue_info);
1189extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
1190 enum ath5k_tx_queue queue_type,
1191 struct ath5k_txq_info *queue_info);
1192extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
1016extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1193extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1017extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1194extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1018extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
1019extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
1020extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah); 1195extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah);
1196extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
1197
1021/* Hardware Descriptor Functions */ 1198/* Hardware Descriptor Functions */
1022extern int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, u32 size, unsigned int flags); 1199extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
1200
1023/* GPIO Functions */ 1201/* GPIO Functions */
1024extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); 1202extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
1025extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
1026extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); 1203extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
1204extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
1027extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); 1205extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
1028extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); 1206extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
1029extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); 1207extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
1208
1030/* Misc functions */ 1209/* Misc functions */
1210int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
1031extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); 1211extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
1032 1212extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
1213extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
1033 1214
1034/* Initial register settings functions */ 1215/* Initial register settings functions */
1035extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); 1216extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
1217
1036/* Initialize RF */ 1218/* Initialize RF */
1037extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode); 1219extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode);
1038extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq); 1220extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq);
1039extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah); 1221extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah);
1040extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah); 1222extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah);
1041
1042
1043/* PHY/RF channel functions */ 1223/* PHY/RF channel functions */
1044extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); 1224extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
1045extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1225extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1046/* PHY calibration */ 1226/* PHY calibration */
1047extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1227extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1048extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1228extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
1049/* Misc PHY functions */ 1229/* Misc PHY functions */
1050extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); 1230extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1051extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant); 1231extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
1052extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah); 1232extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1053extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); 1233extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1054/* TX power setup */ 1234/* TX power setup */
1055extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower); 1235extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower);
1056extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power); 1236extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
1057 1237
1238/*
1239 * Functions used internaly
1240 */
1241
1242/*
1243 * Translate usec to hw clock units
1244 */
1245static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
1246{
1247 return turbo ? (usec * 80) : (usec * 40);
1248}
1058 1249
1250/*
1251 * Translate hw clock units to usec
1252 */
1253static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
1254{
1255 return turbo ? (clock / 80) : (clock / 40);
1256}
1257
1258/*
1259 * Read from a register
1260 */
1059static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) 1261static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
1060{ 1262{
1061 return ioread32(ah->ah_iobase + reg); 1263 return ioread32(ah->ah_iobase + reg);
1062} 1264}
1063 1265
1266/*
1267 * Write to a register
1268 */
1064static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) 1269static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
1065{ 1270{
1066 iowrite32(val, ah->ah_iobase + reg); 1271 iowrite32(val, ah->ah_iobase + reg);
1067} 1272}
1068 1273
1274#if defined(_ATH5K_RESET) || defined(_ATH5K_PHY)
1275/*
1276 * Check if a register write has been completed
1277 */
1278static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag,
1279 u32 val, bool is_set)
1280{
1281 int i;
1282 u32 data;
1283
1284 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
1285 data = ath5k_hw_reg_read(ah, reg);
1286 if (is_set && (data & flag))
1287 break;
1288 else if ((data & flag) == val)
1289 break;
1290 udelay(15);
1291 }
1292
1293 return (i <= 0) ? -EAGAIN : 0;
1294}
1295#endif
1296
1297static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1298{
1299 u32 retval = 0, bit, i;
1300
1301 for (i = 0; i < bits; i++) {
1302 bit = (val >> i) & 1;
1303 retval = (retval << 1) | bit;
1304 }
1305
1306 return retval;
1307}
1308
1069#endif 1309#endif
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c
new file mode 100644
index 000000000000..0eb2511fe147
--- /dev/null
+++ b/drivers/net/wireless/ath5k/attach.c
@@ -0,0 +1,315 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 */
18
19/*************************************\
20* Attach/Detach Functions and helpers *
21\*************************************/
22
23#include <linux/pci.h>
24#include "ath5k.h"
25#include "reg.h"
26#include "debug.h"
27#include "base.h"
28
29/**
30 * ath5k_hw_post - Power On Self Test helper function
31 *
32 * @ah: The &struct ath5k_hw
33 */
34static int ath5k_hw_post(struct ath5k_hw *ah)
35{
36
37 int i, c;
38 u16 cur_reg;
39 u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
40 u32 var_pattern;
41 u32 static_pattern[4] = {
42 0x55555555, 0xaaaaaaaa,
43 0x66666666, 0x99999999
44 };
45 u32 init_val;
46 u32 cur_val;
47
48 for (c = 0; c < 2; c++) {
49
50 cur_reg = regs[c];
51
52 /* Save previous value */
53 init_val = ath5k_hw_reg_read(ah, cur_reg);
54
55 for (i = 0; i < 256; i++) {
56 var_pattern = i << 16 | i;
57 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
58 cur_val = ath5k_hw_reg_read(ah, cur_reg);
59
60 if (cur_val != var_pattern) {
61 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
62 return -EAGAIN;
63 }
64
65 /* Found on ndiswrapper dumps */
66 var_pattern = 0x0039080f;
67 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
68 }
69
70 for (i = 0; i < 4; i++) {
71 var_pattern = static_pattern[i];
72 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
73 cur_val = ath5k_hw_reg_read(ah, cur_reg);
74
75 if (cur_val != var_pattern) {
76 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
77 return -EAGAIN;
78 }
79
80 /* Found on ndiswrapper dumps */
81 var_pattern = 0x003b080f;
82 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
83 }
84
85 /* Restore previous value */
86 ath5k_hw_reg_write(ah, init_val, cur_reg);
87
88 }
89
90 return 0;
91
92}
93
94/**
95 * ath5k_hw_attach - Check if hw is supported and init the needed structs
96 *
97 * @sc: The &struct ath5k_softc we got from the driver's attach function
98 * @mac_version: The mac version id (check out ath5k.h) based on pci id
99 *
100 * Check if the device is supported, perform a POST and initialize the needed
101 * structs. Returns -ENOMEM if we don't have memory for the needed structs,
102 * -ENODEV if the device is not supported or prints an error msg if something
103 * else went wrong.
104 */
105struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
106{
107 struct ath5k_hw *ah;
108 struct pci_dev *pdev = sc->pdev;
109 u8 mac[ETH_ALEN];
110 int ret;
111 u32 srev;
112
113 /*If we passed the test malloc a ath5k_hw struct*/
114 ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
115 if (ah == NULL) {
116 ret = -ENOMEM;
117 ATH5K_ERR(sc, "out of memory\n");
118 goto err;
119 }
120
121 ah->ah_sc = sc;
122 ah->ah_iobase = sc->iobase;
123
124 /*
125 * HW information
126 */
127 ah->ah_op_mode = IEEE80211_IF_TYPE_STA;
128 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
129 ah->ah_turbo = false;
130 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
131 ah->ah_imr = 0;
132 ah->ah_atim_window = 0;
133 ah->ah_aifs = AR5K_TUNE_AIFS;
134 ah->ah_cw_min = AR5K_TUNE_CWMIN;
135 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
136 ah->ah_software_retry = false;
137 ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
138
139 /*
140 * Set the mac revision based on the pci id
141 */
142 ah->ah_version = mac_version;
143
144 /*Fill the ath5k_hw struct with the needed functions*/
145 ret = ath5k_hw_init_desc_functions(ah);
146 if (ret)
147 goto err_free;
148
149 /* Bring device out of sleep and reset it's units */
150 ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
151 if (ret)
152 goto err_free;
153
154 /* Get MAC, PHY and RADIO revisions */
155 srev = ath5k_hw_reg_read(ah, AR5K_SREV);
156 ah->ah_mac_srev = srev;
157 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
158 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
159 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
160 0xffffffff;
161 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
162 CHANNEL_5GHZ);
163
164 if (ah->ah_version == AR5K_AR5210)
165 ah->ah_radio_2ghz_revision = 0;
166 else
167 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
168 CHANNEL_2GHZ);
169
170 /* Return on unsuported chips (unsupported eeprom etc) */
171 if ((srev >= AR5K_SREV_VER_AR5416) &&
172 (srev < AR5K_SREV_VER_AR2425)) {
173 ATH5K_ERR(sc, "Device not yet supported.\n");
174 ret = -ENODEV;
175 goto err_free;
176 } else if (srev == AR5K_SREV_VER_AR2425) {
177 ATH5K_WARN(sc, "Support for RF2425 is under development.\n");
178 }
179
180 /* Identify single chip solutions */
181 if (((srev <= AR5K_SREV_VER_AR5414) &&
182 (srev >= AR5K_SREV_VER_AR2413)) ||
183 (srev == AR5K_SREV_VER_AR2425)) {
184 ah->ah_single_chip = true;
185 } else {
186 ah->ah_single_chip = false;
187 }
188
189 /* Single chip radio */
190 if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
191 ah->ah_radio_2ghz_revision = 0;
192
193 /* Identify the radio chip*/
194 if (ah->ah_version == AR5K_AR5210) {
195 ah->ah_radio = AR5K_RF5110;
196 /*
197 * Register returns 0x0/0x04 for radio revision
198 * so ath5k_hw_radio_revision doesn't parse the value
199 * correctly. For now we are based on mac's srev to
200 * identify RF2425 radio.
201 */
202 } else if (srev == AR5K_SREV_VER_AR2425) {
203 ah->ah_radio = AR5K_RF2425;
204 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
205 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
206 ah->ah_radio = AR5K_RF5111;
207 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
208 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
209 ah->ah_radio = AR5K_RF5112;
210 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
211 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
212 ah->ah_radio = AR5K_RF2413;
213 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
214 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
215 ah->ah_radio = AR5K_RF5413;
216 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
217 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
218 /* AR5424 */
219 if (srev >= AR5K_SREV_VER_AR5424) {
220 ah->ah_radio = AR5K_RF5413;
221 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
222 /* AR2424 */
223 } else {
224 ah->ah_radio = AR5K_RF2413; /* For testing */
225 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
226 }
227 }
228 ah->ah_phy = AR5K_PHY(0);
229
230 /*
231 * Write PCI-E power save settings
232 */
233 if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
234 ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
235 ath5k_hw_reg_write(ah, 0x24924924, 0x4080);
236 ath5k_hw_reg_write(ah, 0x28000039, 0x4080);
237 ath5k_hw_reg_write(ah, 0x53160824, 0x4080);
238 ath5k_hw_reg_write(ah, 0xe5980579, 0x4080);
239 ath5k_hw_reg_write(ah, 0x001defff, 0x4080);
240 ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080);
241 ath5k_hw_reg_write(ah, 0xbe105554, 0x4080);
242 ath5k_hw_reg_write(ah, 0x000e3007, 0x4080);
243 ath5k_hw_reg_write(ah, 0x00000000, 0x4084);
244 }
245
246 /*
247 * POST
248 */
249 ret = ath5k_hw_post(ah);
250 if (ret)
251 goto err_free;
252
253 /* Write AR5K_PCICFG_UNK on 2112B and later chips */
254 if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B ||
255 srev > AR5K_SREV_VER_AR2413) {
256 ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG);
257 }
258
259 /*
260 * Get card capabilities, values, ...
261 */
262 ret = ath5k_eeprom_init(ah);
263 if (ret) {
264 ATH5K_ERR(sc, "unable to init EEPROM\n");
265 goto err_free;
266 }
267
268 /* Get misc capabilities */
269 ret = ath5k_hw_set_capabilities(ah);
270 if (ret) {
271 ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
272 sc->pdev->device);
273 goto err_free;
274 }
275
276 /* Get MAC address */
277 ret = ath5k_eeprom_read_mac(ah, mac);
278 if (ret) {
279 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
280 sc->pdev->device);
281 goto err_free;
282 }
283
284 ath5k_hw_set_lladdr(ah, mac);
285 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
286 memset(ah->ah_bssid, 0xff, ETH_ALEN);
287 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
288 ath5k_hw_set_opmode(ah);
289
290 ath5k_hw_set_rfgain_opt(ah);
291
292 return ah;
293err_free:
294 kfree(ah);
295err:
296 return ERR_PTR(ret);
297}
298
299/**
300 * ath5k_hw_detach - Free the ath5k_hw struct
301 *
302 * @ah: The &struct ath5k_hw
303 */
304void ath5k_hw_detach(struct ath5k_hw *ah)
305{
306 ATH5K_TRACE(ah->ah_sc);
307
308 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
309
310 if (ah->ah_rf_banks != NULL)
311 kfree(ah->ah_rf_banks);
312
313 /* assume interrupts are down */
314 kfree(ah);
315}
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index bcec74e839e9..85260c39aa2b 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -485,6 +485,12 @@ ath5k_pci_probe(struct pci_dev *pdev,
485 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 485 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
486 IEEE80211_HW_SIGNAL_DBM | 486 IEEE80211_HW_SIGNAL_DBM |
487 IEEE80211_HW_NOISE_DBM; 487 IEEE80211_HW_NOISE_DBM;
488
489 hw->wiphy->interface_modes =
490 BIT(NL80211_IFTYPE_STATION) |
491 BIT(NL80211_IFTYPE_ADHOC) |
492 BIT(NL80211_IFTYPE_MESH_POINT);
493
488 hw->extra_tx_headroom = 2; 494 hw->extra_tx_headroom = 2;
489 hw->channel_change_time = 5000; 495 hw->channel_change_time = 5000;
490 sc = hw->priv; 496 sc = hw->priv;
@@ -707,7 +713,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
707 * return false w/o doing anything. MAC's that do 713 * return false w/o doing anything. MAC's that do
708 * support it will return true w/o doing anything. 714 * support it will return true w/o doing anything.
709 */ 715 */
710 ret = ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); 716 ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
711 if (ret < 0) 717 if (ret < 0)
712 goto err; 718 goto err;
713 if (ret > 0) 719 if (ret > 0)
@@ -1137,7 +1143,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1137 ds = bf->desc; 1143 ds = bf->desc;
1138 ds->ds_link = bf->daddr; /* link to self */ 1144 ds->ds_link = bf->daddr; /* link to self */
1139 ds->ds_data = bf->skbaddr; 1145 ds->ds_data = bf->skbaddr;
1140 ath5k_hw_setup_rx_desc(ah, ds, 1146 ah->ah_setup_rx_desc(ah, ds,
1141 skb_tailroom(skb), /* buffer size */ 1147 skb_tailroom(skb), /* buffer size */
1142 0); 1148 0);
1143 1149
@@ -1188,12 +1194,12 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1188 list_add_tail(&bf->list, &txq->q); 1194 list_add_tail(&bf->list, &txq->q);
1189 sc->tx_stats[txq->qnum].len++; 1195 sc->tx_stats[txq->qnum].len++;
1190 if (txq->link == NULL) /* is this first packet? */ 1196 if (txq->link == NULL) /* is this first packet? */
1191 ath5k_hw_put_tx_buf(ah, txq->qnum, bf->daddr); 1197 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
1192 else /* no, so only link it */ 1198 else /* no, so only link it */
1193 *txq->link = bf->daddr; 1199 *txq->link = bf->daddr;
1194 1200
1195 txq->link = &ds->ds_link; 1201 txq->link = &ds->ds_link;
1196 ath5k_hw_tx_start(ah, txq->qnum); 1202 ath5k_hw_start_tx_dma(ah, txq->qnum);
1197 mmiowb(); 1203 mmiowb();
1198 spin_unlock_bh(&txq->lock); 1204 spin_unlock_bh(&txq->lock);
1199 1205
@@ -1393,7 +1399,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1393 "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n", 1399 "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n",
1394 qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max); 1400 qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max);
1395 1401
1396 ret = ath5k_hw_setup_tx_queueprops(ah, sc->bhalq, &qi); 1402 ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi);
1397 if (ret) { 1403 if (ret) {
1398 ATH5K_ERR(sc, "%s: unable to update parameters for beacon " 1404 ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
1399 "hardware queue!\n", __func__); 1405 "hardware queue!\n", __func__);
@@ -1442,14 +1448,14 @@ ath5k_txq_cleanup(struct ath5k_softc *sc)
1442 /* don't touch the hardware if marked invalid */ 1448 /* don't touch the hardware if marked invalid */
1443 ath5k_hw_stop_tx_dma(ah, sc->bhalq); 1449 ath5k_hw_stop_tx_dma(ah, sc->bhalq);
1444 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", 1450 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",
1445 ath5k_hw_get_tx_buf(ah, sc->bhalq)); 1451 ath5k_hw_get_txdp(ah, sc->bhalq));
1446 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) 1452 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
1447 if (sc->txqs[i].setup) { 1453 if (sc->txqs[i].setup) {
1448 ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); 1454 ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
1449 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " 1455 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
1450 "link %p\n", 1456 "link %p\n",
1451 sc->txqs[i].qnum, 1457 sc->txqs[i].qnum,
1452 ath5k_hw_get_tx_buf(ah, 1458 ath5k_hw_get_txdp(ah,
1453 sc->txqs[i].qnum), 1459 sc->txqs[i].qnum),
1454 sc->txqs[i].link); 1460 sc->txqs[i].link);
1455 } 1461 }
@@ -1509,8 +1515,8 @@ ath5k_rx_start(struct ath5k_softc *sc)
1509 bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); 1515 bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
1510 spin_unlock_bh(&sc->rxbuflock); 1516 spin_unlock_bh(&sc->rxbuflock);
1511 1517
1512 ath5k_hw_put_rx_buf(ah, bf->daddr); 1518 ath5k_hw_set_rxdp(ah, bf->daddr);
1513 ath5k_hw_start_rx(ah); /* enable recv descriptors */ 1519 ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */
1514 ath5k_mode_setup(sc); /* set filters, etc. */ 1520 ath5k_mode_setup(sc); /* set filters, etc. */
1515 ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ 1521 ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
1516 1522
@@ -1527,7 +1533,7 @@ ath5k_rx_stop(struct ath5k_softc *sc)
1527{ 1533{
1528 struct ath5k_hw *ah = sc->ah; 1534 struct ath5k_hw *ah = sc->ah;
1529 1535
1530 ath5k_hw_stop_pcu_recv(ah); /* disable PCU */ 1536 ath5k_hw_stop_rx_pcu(ah); /* disable PCU */
1531 ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ 1537 ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */
1532 ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ 1538 ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */
1533 1539
@@ -1976,8 +1982,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
1976 /* NB: hw still stops DMA, so proceed */ 1982 /* NB: hw still stops DMA, so proceed */
1977 } 1983 }
1978 1984
1979 ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr); 1985 ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
1980 ath5k_hw_tx_start(ah, sc->bhalq); 1986 ath5k_hw_start_tx_dma(ah, sc->bhalq);
1981 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", 1987 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
1982 sc->bhalq, (unsigned long long)bf->daddr, bf->desc); 1988 sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
1983 1989
@@ -2106,7 +2112,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2106{ 2112{
2107 struct ath5k_hw *ah = sc->ah; 2113 struct ath5k_hw *ah = sc->ah;
2108 2114
2109 ath5k_hw_set_intr(ah, 0); 2115 ath5k_hw_set_imr(ah, 0);
2110 sc->bmisscount = 0; 2116 sc->bmisscount = 0;
2111 sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); 2117 sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
2112 2118
@@ -2132,7 +2138,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2132 } 2138 }
2133 /* TODO else AP */ 2139 /* TODO else AP */
2134 2140
2135 ath5k_hw_set_intr(ah, sc->imask); 2141 ath5k_hw_set_imr(ah, sc->imask);
2136} 2142}
2137 2143
2138 2144
@@ -2211,7 +2217,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
2211 2217
2212 if (!test_bit(ATH_STAT_INVALID, sc->status)) { 2218 if (!test_bit(ATH_STAT_INVALID, sc->status)) {
2213 ath5k_led_off(sc); 2219 ath5k_led_off(sc);
2214 ath5k_hw_set_intr(ah, 0); 2220 ath5k_hw_set_imr(ah, 0);
2215 synchronize_irq(sc->pdev->irq); 2221 synchronize_irq(sc->pdev->irq);
2216 } 2222 }
2217 ath5k_txq_cleanup(sc); 2223 ath5k_txq_cleanup(sc);
@@ -2604,7 +2610,7 @@ ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
2604 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); 2610 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
2605 2611
2606 if (stop) { 2612 if (stop) {
2607 ath5k_hw_set_intr(ah, 0); 2613 ath5k_hw_set_imr(ah, 0);
2608 ath5k_txq_cleanup(sc); 2614 ath5k_txq_cleanup(sc);
2609 ath5k_rx_stop(sc); 2615 ath5k_rx_stop(sc);
2610 } 2616 }
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath5k/caps.c
new file mode 100644
index 000000000000..150f5ed204a0
--- /dev/null
+++ b/drivers/net/wireless/ath5k/caps.c
@@ -0,0 +1,193 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20/**************\
21* Capabilities *
22\**************/
23
24#include "ath5k.h"
25#include "reg.h"
26#include "debug.h"
27#include "base.h"
28
29/*
30 * Fill the capabilities struct
31 * TODO: Merge this with EEPROM code when we are done with it
32 */
33int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
34{
35 u16 ee_header;
36
37 ATH5K_TRACE(ah->ah_sc);
38 /* Capabilities stored in the EEPROM */
39 ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
40
41 if (ah->ah_version == AR5K_AR5210) {
42 /*
43 * Set radio capabilities
44 * (The AR5110 only supports the middle 5GHz band)
45 */
46 ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
47 ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
48 ah->ah_capabilities.cap_range.range_2ghz_min = 0;
49 ah->ah_capabilities.cap_range.range_2ghz_max = 0;
50
51 /* Set supported modes */
52 __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
53 __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
54 } else {
55 /*
56 * XXX The tranceiver supports frequencies from 4920 to 6100GHz
57 * XXX and from 2312 to 2732GHz. There are problems with the
58 * XXX current ieee80211 implementation because the IEEE
59 * XXX channel mapping does not support negative channel
60 * XXX numbers (2312MHz is channel -19). Of course, this
61 * XXX doesn't matter because these channels are out of range
62 * XXX but some regulation domains like MKK (Japan) will
63 * XXX support frequencies somewhere around 4.8GHz.
64 */
65
66 /*
67 * Set radio capabilities
68 */
69
70 if (AR5K_EEPROM_HDR_11A(ee_header)) {
71 /* 4920 */
72 ah->ah_capabilities.cap_range.range_5ghz_min = 5005;
73 ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
74
75 /* Set supported modes */
76 __set_bit(AR5K_MODE_11A,
77 ah->ah_capabilities.cap_mode);
78 __set_bit(AR5K_MODE_11A_TURBO,
79 ah->ah_capabilities.cap_mode);
80 if (ah->ah_version == AR5K_AR5212)
81 __set_bit(AR5K_MODE_11G_TURBO,
82 ah->ah_capabilities.cap_mode);
83 }
84
85 /* Enable 802.11b if a 2GHz capable radio (2111/5112) is
86 * connected */
87 if (AR5K_EEPROM_HDR_11B(ee_header) ||
88 AR5K_EEPROM_HDR_11G(ee_header)) {
89 /* 2312 */
90 ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
91 ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
92
93 if (AR5K_EEPROM_HDR_11B(ee_header))
94 __set_bit(AR5K_MODE_11B,
95 ah->ah_capabilities.cap_mode);
96
97 if (AR5K_EEPROM_HDR_11G(ee_header))
98 __set_bit(AR5K_MODE_11G,
99 ah->ah_capabilities.cap_mode);
100 }
101 }
102
103 /* GPIO */
104 ah->ah_gpio_npins = AR5K_NUM_GPIO;
105
106 /* Set number of supported TX queues */
107 if (ah->ah_version == AR5K_AR5210)
108 ah->ah_capabilities.cap_queues.q_tx_num =
109 AR5K_NUM_TX_QUEUES_NOQCU;
110 else
111 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
112
113 return 0;
114}
115
116/* Main function used by the driver part to check caps */
117int ath5k_hw_get_capability(struct ath5k_hw *ah,
118 enum ath5k_capability_type cap_type,
119 u32 capability, u32 *result)
120{
121 ATH5K_TRACE(ah->ah_sc);
122
123 switch (cap_type) {
124 case AR5K_CAP_NUM_TXQUEUES:
125 if (result) {
126 if (ah->ah_version == AR5K_AR5210)
127 *result = AR5K_NUM_TX_QUEUES_NOQCU;
128 else
129 *result = AR5K_NUM_TX_QUEUES;
130 goto yes;
131 }
132 case AR5K_CAP_VEOL:
133 goto yes;
134 case AR5K_CAP_COMPRESSION:
135 if (ah->ah_version == AR5K_AR5212)
136 goto yes;
137 else
138 goto no;
139 case AR5K_CAP_BURST:
140 goto yes;
141 case AR5K_CAP_TPC:
142 goto yes;
143 case AR5K_CAP_BSSIDMASK:
144 if (ah->ah_version == AR5K_AR5212)
145 goto yes;
146 else
147 goto no;
148 case AR5K_CAP_XR:
149 if (ah->ah_version == AR5K_AR5212)
150 goto yes;
151 else
152 goto no;
153 default:
154 goto no;
155 }
156
157no:
158 return -EINVAL;
159yes:
160 return 0;
161}
162
163/*
164 * TODO: Following functions should be part of a new function
165 * set_capability
166 */
167
168int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
169 u16 assoc_id)
170{
171 ATH5K_TRACE(ah->ah_sc);
172
173 if (ah->ah_version == AR5K_AR5210) {
174 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
175 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
176 return 0;
177 }
178
179 return -EIO;
180}
181
182int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
183{
184 ATH5K_TRACE(ah->ah_sc);
185
186 if (ah->ah_version == AR5K_AR5210) {
187 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
188 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
189 return 0;
190 }
191
192 return -EIO;
193}
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
index 6fa6c8e04ff0..8f92d670f614 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath5k/debug.c
@@ -58,8 +58,8 @@
58 * THE POSSIBILITY OF SUCH DAMAGES. 58 * THE POSSIBILITY OF SUCH DAMAGES.
59 */ 59 */
60 60
61#include "debug.h"
62#include "base.h" 61#include "base.h"
62#include "debug.h"
63 63
64static unsigned int ath5k_debug; 64static unsigned int ath5k_debug;
65module_param_named(debug, ath5k_debug, uint, 0); 65module_param_named(debug, ath5k_debug, uint, 0);
@@ -525,7 +525,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
525 return; 525 return;
526 526
527 printk(KERN_DEBUG "rx queue %x, link %p\n", 527 printk(KERN_DEBUG "rx queue %x, link %p\n",
528 ath5k_hw_get_rx_buf(ah), sc->rxlink); 528 ath5k_hw_get_rxdp(ah), sc->rxlink);
529 529
530 spin_lock_bh(&sc->rxbuflock); 530 spin_lock_bh(&sc->rxbuflock);
531 list_for_each_entry(bf, &sc->rxbuf, list) { 531 list_for_each_entry(bf, &sc->rxbuf, list) {
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c
new file mode 100644
index 000000000000..d45b90a6e06c
--- /dev/null
+++ b/drivers/net/wireless/ath5k/desc.c
@@ -0,0 +1,667 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20/******************************\
21 Hardware Descriptor Functions
22\******************************/
23
24#include "ath5k.h"
25#include "reg.h"
26#include "debug.h"
27#include "base.h"
28
29/*
30 * TX Descriptors
31 */
32
33/*
34 * Initialize the 2-word tx control descriptor on 5210/5211
35 */
36static int
37ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
38 unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
39 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
40 unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
41 unsigned int rtscts_rate, unsigned int rtscts_duration)
42{
43 u32 frame_type;
44 struct ath5k_hw_2w_tx_ctl *tx_ctl;
45 unsigned int frame_len;
46
47 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
48
49 /*
50 * Validate input
51 * - Zero retries don't make sense.
52 * - A zero rate will put the HW into a mode where it continously sends
53 * noise on the channel, so it is important to avoid this.
54 */
55 if (unlikely(tx_tries0 == 0)) {
56 ATH5K_ERR(ah->ah_sc, "zero retries\n");
57 WARN_ON(1);
58 return -EINVAL;
59 }
60 if (unlikely(tx_rate0 == 0)) {
61 ATH5K_ERR(ah->ah_sc, "zero rate\n");
62 WARN_ON(1);
63 return -EINVAL;
64 }
65
66 /* Clear descriptor */
67 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
68
69 /* Setup control descriptor */
70
71 /* Verify and set frame length */
72
73 /* remove padding we might have added before */
74 frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
75
76 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
77 return -EINVAL;
78
79 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
80
81 /* Verify and set buffer length */
82
83 /* NB: beacon's BufLen must be a multiple of 4 bytes */
84 if (type == AR5K_PKT_TYPE_BEACON)
85 pkt_len = roundup(pkt_len, 4);
86
87 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
88 return -EINVAL;
89
90 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
91
92 /*
93 * Verify and set header length
94 * XXX: I only found that on 5210 code, does it work on 5211 ?
95 */
96 if (ah->ah_version == AR5K_AR5210) {
97 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
98 return -EINVAL;
99 tx_ctl->tx_control_0 |=
100 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
101 }
102
103 /*Diferences between 5210-5211*/
104 if (ah->ah_version == AR5K_AR5210) {
105 switch (type) {
106 case AR5K_PKT_TYPE_BEACON:
107 case AR5K_PKT_TYPE_PROBE_RESP:
108 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
109 case AR5K_PKT_TYPE_PIFS:
110 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
111 default:
112 frame_type = type /*<< 2 ?*/;
113 }
114
115 tx_ctl->tx_control_0 |=
116 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
117 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
118
119 } else {
120 tx_ctl->tx_control_0 |=
121 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
122 AR5K_REG_SM(antenna_mode,
123 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
124 tx_ctl->tx_control_1 |=
125 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
126 }
127#define _TX_FLAGS(_c, _flag) \
128 if (flags & AR5K_TXDESC_##_flag) { \
129 tx_ctl->tx_control_##_c |= \
130 AR5K_2W_TX_DESC_CTL##_c##_##_flag; \
131 }
132
133 _TX_FLAGS(0, CLRDMASK);
134 _TX_FLAGS(0, VEOL);
135 _TX_FLAGS(0, INTREQ);
136 _TX_FLAGS(0, RTSENA);
137 _TX_FLAGS(1, NOACK);
138
139#undef _TX_FLAGS
140
141 /*
142 * WEP crap
143 */
144 if (key_index != AR5K_TXKEYIX_INVALID) {
145 tx_ctl->tx_control_0 |=
146 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
147 tx_ctl->tx_control_1 |=
148 AR5K_REG_SM(key_index,
149 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
150 }
151
152 /*
153 * RTS/CTS Duration [5210 ?]
154 */
155 if ((ah->ah_version == AR5K_AR5210) &&
156 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
157 tx_ctl->tx_control_1 |= rtscts_duration &
158 AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
159
160 return 0;
161}
162
163/*
164 * Initialize the 4-word tx control descriptor on 5212
165 */
166static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
167 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
168 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
169 unsigned int tx_tries0, unsigned int key_index,
170 unsigned int antenna_mode, unsigned int flags,
171 unsigned int rtscts_rate,
172 unsigned int rtscts_duration)
173{
174 struct ath5k_hw_4w_tx_ctl *tx_ctl;
175 unsigned int frame_len;
176
177 ATH5K_TRACE(ah->ah_sc);
178 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
179
180 /*
181 * Validate input
182 * - Zero retries don't make sense.
183 * - A zero rate will put the HW into a mode where it continously sends
184 * noise on the channel, so it is important to avoid this.
185 */
186 if (unlikely(tx_tries0 == 0)) {
187 ATH5K_ERR(ah->ah_sc, "zero retries\n");
188 WARN_ON(1);
189 return -EINVAL;
190 }
191 if (unlikely(tx_rate0 == 0)) {
192 ATH5K_ERR(ah->ah_sc, "zero rate\n");
193 WARN_ON(1);
194 return -EINVAL;
195 }
196
197 /* Clear descriptor */
198 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
199
200 /* Setup control descriptor */
201
202 /* Verify and set frame length */
203
204 /* remove padding we might have added before */
205 frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
206
207 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
208 return -EINVAL;
209
210 tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
211
212 /* Verify and set buffer length */
213
214 /* NB: beacon's BufLen must be a multiple of 4 bytes */
215 if (type == AR5K_PKT_TYPE_BEACON)
216 pkt_len = roundup(pkt_len, 4);
217
218 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
219 return -EINVAL;
220
221 tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
222
223 tx_ctl->tx_control_0 |=
224 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
225 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
226 tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
227 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
228 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
229 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
230 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
231
232#define _TX_FLAGS(_c, _flag) \
233 if (flags & AR5K_TXDESC_##_flag) { \
234 tx_ctl->tx_control_##_c |= \
235 AR5K_4W_TX_DESC_CTL##_c##_##_flag; \
236 }
237
238 _TX_FLAGS(0, CLRDMASK);
239 _TX_FLAGS(0, VEOL);
240 _TX_FLAGS(0, INTREQ);
241 _TX_FLAGS(0, RTSENA);
242 _TX_FLAGS(0, CTSENA);
243 _TX_FLAGS(1, NOACK);
244
245#undef _TX_FLAGS
246
247 /*
248 * WEP crap
249 */
250 if (key_index != AR5K_TXKEYIX_INVALID) {
251 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
252 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
253 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
254 }
255
256 /*
257 * RTS/CTS
258 */
259 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
260 if ((flags & AR5K_TXDESC_RTSENA) &&
261 (flags & AR5K_TXDESC_CTSENA))
262 return -EINVAL;
263 tx_ctl->tx_control_2 |= rtscts_duration &
264 AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
265 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
266 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
267 }
268
269 return 0;
270}
271
272/*
273 * Initialize a 4-word multi rate retry tx control descriptor on 5212
274 */
275static int
276ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
277 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
278 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
279{
280 struct ath5k_hw_4w_tx_ctl *tx_ctl;
281
282 /*
283 * Rates can be 0 as long as the retry count is 0 too.
284 * A zero rate and nonzero retry count will put the HW into a mode where
285 * it continously sends noise on the channel, so it is important to
286 * avoid this.
287 */
288 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
289 (tx_rate2 == 0 && tx_tries2 != 0) ||
290 (tx_rate3 == 0 && tx_tries3 != 0))) {
291 ATH5K_ERR(ah->ah_sc, "zero rate\n");
292 WARN_ON(1);
293 return -EINVAL;
294 }
295
296 if (ah->ah_version == AR5K_AR5212) {
297 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
298
299#define _XTX_TRIES(_n) \
300 if (tx_tries##_n) { \
301 tx_ctl->tx_control_2 |= \
302 AR5K_REG_SM(tx_tries##_n, \
303 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
304 tx_ctl->tx_control_3 |= \
305 AR5K_REG_SM(tx_rate##_n, \
306 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
307 }
308
309 _XTX_TRIES(1);
310 _XTX_TRIES(2);
311 _XTX_TRIES(3);
312
313#undef _XTX_TRIES
314
315 return 1;
316 }
317
318 return 0;
319}
320
321/*
322 * Proccess the tx status descriptor on 5210/5211
323 */
324static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
325 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
326{
327 struct ath5k_hw_2w_tx_ctl *tx_ctl;
328 struct ath5k_hw_tx_status *tx_status;
329
330 ATH5K_TRACE(ah->ah_sc);
331
332 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
333 tx_status = &desc->ud.ds_tx5210.tx_stat;
334
335 /* No frame has been send or error */
336 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
337 return -EINPROGRESS;
338
339 /*
340 * Get descriptor status
341 */
342 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
343 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
344 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
345 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
346 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
347 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
348 /*TODO: ts->ts_virtcol + test*/
349 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
350 AR5K_DESC_TX_STATUS1_SEQ_NUM);
351 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
352 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
353 ts->ts_antenna = 1;
354 ts->ts_status = 0;
355 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
356 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
357
358 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
359 if (tx_status->tx_status_0 &
360 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
361 ts->ts_status |= AR5K_TXERR_XRETRY;
362
363 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
364 ts->ts_status |= AR5K_TXERR_FIFO;
365
366 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
367 ts->ts_status |= AR5K_TXERR_FILT;
368 }
369
370 return 0;
371}
372
373/*
374 * Proccess a tx status descriptor on 5212
375 */
376static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
377 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
378{
379 struct ath5k_hw_4w_tx_ctl *tx_ctl;
380 struct ath5k_hw_tx_status *tx_status;
381
382 ATH5K_TRACE(ah->ah_sc);
383
384 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
385 tx_status = &desc->ud.ds_tx5212.tx_stat;
386
387 /* No frame has been send or error */
388 if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE)))
389 return -EINPROGRESS;
390
391 /*
392 * Get descriptor status
393 */
394 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
395 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
396 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
397 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
398 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
399 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
400 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
401 AR5K_DESC_TX_STATUS1_SEQ_NUM);
402 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
403 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
404 ts->ts_antenna = (tx_status->tx_status_1 &
405 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
406 ts->ts_status = 0;
407
408 switch (AR5K_REG_MS(tx_status->tx_status_1,
409 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
410 case 0:
411 ts->ts_rate = tx_ctl->tx_control_3 &
412 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
413 break;
414 case 1:
415 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
416 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
417 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
418 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
419 break;
420 case 2:
421 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
422 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
423 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
424 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
425 break;
426 case 3:
427 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
428 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
429 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
430 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
431 break;
432 }
433
434 /* TX error */
435 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
436 if (tx_status->tx_status_0 &
437 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
438 ts->ts_status |= AR5K_TXERR_XRETRY;
439
440 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
441 ts->ts_status |= AR5K_TXERR_FIFO;
442
443 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
444 ts->ts_status |= AR5K_TXERR_FILT;
445 }
446
447 return 0;
448}
449
450/*
451 * RX Descriptors
452 */
453
454/*
455 * Initialize an rx control descriptor
456 */
457static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
458 u32 size, unsigned int flags)
459{
460 struct ath5k_hw_rx_ctl *rx_ctl;
461
462 ATH5K_TRACE(ah->ah_sc);
463 rx_ctl = &desc->ud.ds_rx.rx_ctl;
464
465 /*
466 * Clear the descriptor
467 * If we don't clean the status descriptor,
468 * while scanning we get too many results,
469 * most of them virtual, after some secs
470 * of scanning system hangs. M.F.
471 */
472 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
473
474 /* Setup descriptor */
475 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
476 if (unlikely(rx_ctl->rx_control_1 != size))
477 return -EINVAL;
478
479 if (flags & AR5K_RXDESC_INTREQ)
480 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
481
482 return 0;
483}
484
485/*
486 * Proccess the rx status descriptor on 5210/5211
487 */
488static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
489 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
490{
491 struct ath5k_hw_rx_status *rx_status;
492
493 rx_status = &desc->ud.ds_rx.u.rx_stat;
494
495 /* No frame received / not ready */
496 if (unlikely(!(rx_status->rx_status_1 &
497 AR5K_5210_RX_DESC_STATUS1_DONE)))
498 return -EINPROGRESS;
499
500 /*
501 * Frame receive status
502 */
503 rs->rs_datalen = rx_status->rx_status_0 &
504 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
505 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
506 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
507 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
508 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
509 rs->rs_antenna = rx_status->rx_status_0 &
510 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA;
511 rs->rs_more = rx_status->rx_status_0 &
512 AR5K_5210_RX_DESC_STATUS0_MORE;
513 /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
514 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
515 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
516 rs->rs_status = 0;
517 rs->rs_phyerr = 0;
518
519 /*
520 * Key table status
521 */
522 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
523 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
524 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
525 else
526 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
527
528 /*
529 * Receive/descriptor errors
530 */
531 if (!(rx_status->rx_status_1 &
532 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
533 if (rx_status->rx_status_1 &
534 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
535 rs->rs_status |= AR5K_RXERR_CRC;
536
537 if (rx_status->rx_status_1 &
538 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
539 rs->rs_status |= AR5K_RXERR_FIFO;
540
541 if (rx_status->rx_status_1 &
542 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
543 rs->rs_status |= AR5K_RXERR_PHY;
544 rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1,
545 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
546 }
547
548 if (rx_status->rx_status_1 &
549 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
550 rs->rs_status |= AR5K_RXERR_DECRYPT;
551 }
552
553 return 0;
554}
555
556/*
557 * Proccess the rx status descriptor on 5212
558 */
559static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
560 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
561{
562 struct ath5k_hw_rx_status *rx_status;
563 struct ath5k_hw_rx_error *rx_err;
564
565 ATH5K_TRACE(ah->ah_sc);
566 rx_status = &desc->ud.ds_rx.u.rx_stat;
567
568 /* Overlay on error */
569 rx_err = &desc->ud.ds_rx.u.rx_err;
570
571 /* No frame received / not ready */
572 if (unlikely(!(rx_status->rx_status_1 &
573 AR5K_5212_RX_DESC_STATUS1_DONE)))
574 return -EINPROGRESS;
575
576 /*
577 * Frame receive status
578 */
579 rs->rs_datalen = rx_status->rx_status_0 &
580 AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
581 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
582 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
583 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
584 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
585 rs->rs_antenna = rx_status->rx_status_0 &
586 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA;
587 rs->rs_more = rx_status->rx_status_0 &
588 AR5K_5212_RX_DESC_STATUS0_MORE;
589 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
590 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
591 rs->rs_status = 0;
592 rs->rs_phyerr = 0;
593
594 /*
595 * Key table status
596 */
597 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
598 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
599 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
600 else
601 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
602
603 /*
604 * Receive/descriptor errors
605 */
606 if (!(rx_status->rx_status_1 &
607 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
608 if (rx_status->rx_status_1 &
609 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
610 rs->rs_status |= AR5K_RXERR_CRC;
611
612 if (rx_status->rx_status_1 &
613 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
614 rs->rs_status |= AR5K_RXERR_PHY;
615 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
616 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
617 }
618
619 if (rx_status->rx_status_1 &
620 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
621 rs->rs_status |= AR5K_RXERR_DECRYPT;
622
623 if (rx_status->rx_status_1 &
624 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
625 rs->rs_status |= AR5K_RXERR_MIC;
626 }
627
628 return 0;
629}
630
631/*
632 * Init function pointers inside ath5k_hw struct
633 */
634int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
635{
636
637 if (ah->ah_version != AR5K_AR5210 &&
638 ah->ah_version != AR5K_AR5211 &&
639 ah->ah_version != AR5K_AR5212)
640 return -ENOTSUPP;
641
642 /* XXX: What is this magic value and where is it used ? */
643 if (ah->ah_version == AR5K_AR5212)
644 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
645 else if (ah->ah_version == AR5K_AR5211)
646 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
647
648 if (ah->ah_version == AR5K_AR5212) {
649 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
650 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
651 ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
652 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
653 } else {
654 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
655 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
656 ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
657 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
658 }
659
660 if (ah->ah_version == AR5K_AR5212)
661 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
662 else if (ah->ah_version <= AR5K_AR5211)
663 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
664
665 return 0;
666}
667
diff --git a/drivers/net/wireless/ath5k/hw.h b/drivers/net/wireless/ath5k/desc.h
index 64fca8dcb386..56158c804e3e 100644
--- a/drivers/net/wireless/ath5k/hw.h
+++ b/drivers/net/wireless/ath5k/desc.h
@@ -1,8 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> 2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com> 3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org>
5 * Copyright (c) 2007 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
6 * 4 *
7 * Permission to use, copy, modify, and distribute this software for any 5 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -15,159 +13,9 @@
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
18 */ 17 */
19 18
20#include <linux/delay.h>
21
22/*
23 * Gain settings
24 */
25
26enum ath5k_rfgain {
27 AR5K_RFGAIN_INACTIVE = 0,
28 AR5K_RFGAIN_READ_REQUESTED,
29 AR5K_RFGAIN_NEED_CHANGE,
30};
31
32#define AR5K_GAIN_CRN_FIX_BITS_5111 4
33#define AR5K_GAIN_CRN_FIX_BITS_5112 7
34#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112
35#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15
36#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20
37#define AR5K_GAIN_CCK_PROBE_CORR 5
38#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15
39#define AR5K_GAIN_STEP_COUNT 10
40#define AR5K_GAIN_PARAM_TX_CLIP 0
41#define AR5K_GAIN_PARAM_PD_90 1
42#define AR5K_GAIN_PARAM_PD_84 2
43#define AR5K_GAIN_PARAM_GAIN_SEL 3
44#define AR5K_GAIN_PARAM_MIX_ORN 0
45#define AR5K_GAIN_PARAM_PD_138 1
46#define AR5K_GAIN_PARAM_PD_137 2
47#define AR5K_GAIN_PARAM_PD_136 3
48#define AR5K_GAIN_PARAM_PD_132 4
49#define AR5K_GAIN_PARAM_PD_131 5
50#define AR5K_GAIN_PARAM_PD_130 6
51#define AR5K_GAIN_CHECK_ADJUST(_g) \
52 ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
53
54struct ath5k_gain_opt_step {
55 s16 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
56 s32 gos_gain;
57};
58
59struct ath5k_gain {
60 u32 g_step_idx;
61 u32 g_current;
62 u32 g_target;
63 u32 g_low;
64 u32 g_high;
65 u32 g_f_corr;
66 u32 g_active;
67 const struct ath5k_gain_opt_step *g_step;
68};
69
70
71/*
72 * HW SPECIFIC STRUCTS
73 */
74
75/* Some EEPROM defines */
76#define AR5K_EEPROM_EEP_SCALE 100
77#define AR5K_EEPROM_EEP_DELTA 10
78#define AR5K_EEPROM_N_MODES 3
79#define AR5K_EEPROM_N_5GHZ_CHAN 10
80#define AR5K_EEPROM_N_2GHZ_CHAN 3
81#define AR5K_EEPROM_MAX_CHAN 10
82#define AR5K_EEPROM_N_PCDAC 11
83#define AR5K_EEPROM_N_TEST_FREQ 8
84#define AR5K_EEPROM_N_EDGES 8
85#define AR5K_EEPROM_N_INTERCEPTS 11
86#define AR5K_EEPROM_FREQ_M(_v) AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
87#define AR5K_EEPROM_PCDAC_M 0x3f
88#define AR5K_EEPROM_PCDAC_START 1
89#define AR5K_EEPROM_PCDAC_STOP 63
90#define AR5K_EEPROM_PCDAC_STEP 1
91#define AR5K_EEPROM_NON_EDGE_M 0x40
92#define AR5K_EEPROM_CHANNEL_POWER 8
93#define AR5K_EEPROM_N_OBDB 4
94#define AR5K_EEPROM_OBDB_DIS 0xffff
95#define AR5K_EEPROM_CHANNEL_DIS 0xff
96#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
97#define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32)
98#define AR5K_EEPROM_MAX_CTLS 32
99#define AR5K_EEPROM_N_XPD_PER_CHANNEL 4
100#define AR5K_EEPROM_N_XPD0_POINTS 4
101#define AR5K_EEPROM_N_XPD3_POINTS 3
102#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35
103#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55
104#define AR5K_EEPROM_POWER_M 0x3f
105#define AR5K_EEPROM_POWER_MIN 0
106#define AR5K_EEPROM_POWER_MAX 3150
107#define AR5K_EEPROM_POWER_STEP 50
108#define AR5K_EEPROM_POWER_TABLE_SIZE 64
109#define AR5K_EEPROM_N_POWER_LOC_11B 4
110#define AR5K_EEPROM_N_POWER_LOC_11G 6
111#define AR5K_EEPROM_I_GAIN 10
112#define AR5K_EEPROM_CCK_OFDM_DELTA 15
113#define AR5K_EEPROM_N_IQ_CAL 2
114
115/* Struct to hold EEPROM calibration data */
116struct ath5k_eeprom_info {
117 u16 ee_magic;
118 u16 ee_protect;
119 u16 ee_regdomain;
120 u16 ee_version;
121 u16 ee_header;
122 u16 ee_ant_gain;
123 u16 ee_misc0;
124 u16 ee_misc1;
125 u16 ee_cck_ofdm_gain_delta;
126 u16 ee_cck_ofdm_power_delta;
127 u16 ee_scaled_cck_delta;
128
129 /* Used for tx thermal adjustment (eeprom_init, rfregs) */
130 u16 ee_tx_clip;
131 u16 ee_pwd_84;
132 u16 ee_pwd_90;
133 u16 ee_gain_select;
134
135 /* RF Calibration settings (reset, rfregs) */
136 u16 ee_i_cal[AR5K_EEPROM_N_MODES];
137 u16 ee_q_cal[AR5K_EEPROM_N_MODES];
138 u16 ee_fixed_bias[AR5K_EEPROM_N_MODES];
139 u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES];
140 u16 ee_xr_power[AR5K_EEPROM_N_MODES];
141 u16 ee_switch_settling[AR5K_EEPROM_N_MODES];
142 u16 ee_ant_tx_rx[AR5K_EEPROM_N_MODES];
143 u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
144 u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
145 u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
146 u16 ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
147 u16 ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
148 u16 ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
149 u16 ee_thr_62[AR5K_EEPROM_N_MODES];
150 u16 ee_xlna_gain[AR5K_EEPROM_N_MODES];
151 u16 ee_xpd[AR5K_EEPROM_N_MODES];
152 u16 ee_x_gain[AR5K_EEPROM_N_MODES];
153 u16 ee_i_gain[AR5K_EEPROM_N_MODES];
154 u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
155
156 /* Unused */
157 u16 ee_false_detect[AR5K_EEPROM_N_MODES];
158 u16 ee_cal_pier[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_2GHZ_CHAN];
159 u16 ee_channel[AR5K_EEPROM_N_MODES][AR5K_EEPROM_MAX_CHAN]; /*empty*/
160
161 /* Conformance test limits (Unused) */
162 u16 ee_ctls;
163 u16 ee_ctl[AR5K_EEPROM_MAX_CTLS];
164
165 /* Noise Floor Calibration settings */
166 s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
167 s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES];
168 s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES];
169};
170
171/* 19/*
172 * Internal RX/TX descriptor structures 20 * Internal RX/TX descriptor structures
173 * (rX: reserved fields possibily used by future versions of the ar5k chipset) 21 * (rX: reserved fields possibily used by future versions of the ar5k chipset)
@@ -178,14 +26,15 @@ struct ath5k_eeprom_info {
178 */ 26 */
179struct ath5k_hw_rx_ctl { 27struct ath5k_hw_rx_ctl {
180 u32 rx_control_0; /* RX control word 0 */ 28 u32 rx_control_0; /* RX control word 0 */
29 u32 rx_control_1; /* RX control word 1 */
30} __packed;
181 31
32/* RX control word 0 field/sflags */
182#define AR5K_DESC_RX_CTL0 0x00000000 33#define AR5K_DESC_RX_CTL0 0x00000000
183 34
184 u32 rx_control_1; /* RX control word 1 */ 35/* RX control word 1 fields/flags */
185
186#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff 36#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff
187#define AR5K_DESC_RX_CTL1_INTREQ 0x00002000 37#define AR5K_DESC_RX_CTL1_INTREQ 0x00002000
188} __packed;
189 38
190/* 39/*
191 * common hardware RX status descriptor 40 * common hardware RX status descriptor
@@ -197,6 +46,7 @@ struct ath5k_hw_rx_status {
197} __packed; 46} __packed;
198 47
199/* 5210/5211 */ 48/* 5210/5211 */
49/* RX status word 0 fields/flags */
200#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff 50#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff
201#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 51#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000
202#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 52#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000
@@ -205,6 +55,8 @@ struct ath5k_hw_rx_status {
205#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19 55#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19
206#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000 56#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000
207#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27 57#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27
58
59/* RX status word 1 fields/flags */
208#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 60#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001
209#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 61#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
210#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 62#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004
@@ -220,6 +72,7 @@ struct ath5k_hw_rx_status {
220#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 72#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000
221 73
222/* 5212 */ 74/* 5212 */
75/* RX status word 0 fields/flags */
223#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff 76#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff
224#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 77#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000
225#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 78#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000
@@ -229,6 +82,8 @@ struct ath5k_hw_rx_status {
229#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20 82#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20
230#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 83#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000
231#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28 84#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28
85
86/* RX status word 1 fields/flags */
232#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 87#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001
233#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 88#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
234#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 89#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004
@@ -246,16 +101,18 @@ struct ath5k_hw_rx_status {
246 * common hardware RX error descriptor 101 * common hardware RX error descriptor
247 */ 102 */
248struct ath5k_hw_rx_error { 103struct ath5k_hw_rx_error {
249 u32 rx_error_0; /* RX error word 0 */ 104 u32 rx_error_0; /* RX status word 0 */
105 u32 rx_error_1; /* RX status word 1 */
106} __packed;
250 107
108/* RX error word 0 fields/flags */
251#define AR5K_RX_DESC_ERROR0 0x00000000 109#define AR5K_RX_DESC_ERROR0 0x00000000
252 110
253 u32 rx_error_1; /* RX error word 1 */ 111/* RX error word 1 fields/flags */
254
255#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 112#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00
256#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 113#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8
257} __packed;
258 114
115/* PHY Error codes */
259#define AR5K_DESC_RX_PHY_ERROR_NONE 0x00 116#define AR5K_DESC_RX_PHY_ERROR_NONE 0x00
260#define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20 117#define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20
261#define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40 118#define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40
@@ -270,7 +127,10 @@ struct ath5k_hw_rx_error {
270 */ 127 */
271struct ath5k_hw_2w_tx_ctl { 128struct ath5k_hw_2w_tx_ctl {
272 u32 tx_control_0; /* TX control word 0 */ 129 u32 tx_control_0; /* TX control word 0 */
130 u32 tx_control_1; /* TX control word 1 */
131} __packed;
273 132
133/* TX control word 0 fields/flags */
274#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff 134#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff
275#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN 0x0003f000 /*[5210 ?]*/ 135#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN 0x0003f000 /*[5210 ?]*/
276#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S 12 136#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S 12
@@ -284,29 +144,34 @@ struct ath5k_hw_2w_tx_ctl {
284#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S 26 144#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S 26
285#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000 145#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000
286#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000 146#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000
287#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT (ah->ah_version == AR5K_AR5210 ? \ 147
288 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \ 148#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT \
289 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211) 149 (ah->ah_version == AR5K_AR5210 ? \
150 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \
151 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211)
152
290#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 153#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25
291#define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000 154#define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000
292#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 155#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
293 156
294 u32 tx_control_1; /* TX control word 1 */ 157/* TX control word 1 fields/flags */
295
296#define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff 158#define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff
297#define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000 159#define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000
298#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 0x0007e000 160#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 0x0007e000
299#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211 0x000fe000 161#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211 0x000fe000
300#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX (ah->ah_version == AR5K_AR5210 ? \ 162
301 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 : \ 163#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX \
302 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211) 164 (ah->ah_version == AR5K_AR5210 ? \
165 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 : \
166 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211)
167
303#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13 168#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13
304#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE 0x00700000 /*[5211]*/ 169#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE 0x00700000 /*[5211]*/
305#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S 20 170#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S 20
306#define AR5K_2W_TX_DESC_CTL1_NOACK 0x00800000 /*[5211]*/ 171#define AR5K_2W_TX_DESC_CTL1_NOACK 0x00800000 /*[5211]*/
307#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION 0xfff80000 /*[5210 ?]*/ 172#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION 0xfff80000 /*[5210 ?]*/
308} __packed;
309 173
174/* Frame types */
310#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0x00 175#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0x00
311#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 0x04 176#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 0x04
312#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 0x08 177#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 0x08
@@ -378,7 +243,10 @@ struct ath5k_hw_4w_tx_ctl {
378 */ 243 */
379struct ath5k_hw_tx_status { 244struct ath5k_hw_tx_status {
380 u32 tx_status_0; /* TX status word 0 */ 245 u32 tx_status_0; /* TX status word 0 */
246 u32 tx_status_1; /* TX status word 1 */
247} __packed;
381 248
249/* TX status word 0 fields/flags */
382#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 250#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001
383#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002 251#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002
384#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004 252#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004
@@ -400,8 +268,7 @@ struct ath5k_hw_tx_status {
400#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000 268#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000
401#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16 269#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16
402 270
403 u32 tx_status_1; /* TX status word 1 */ 271/* TX status word 1 fields/flags */
404
405#define AR5K_DESC_TX_STATUS1_DONE 0x00000001 272#define AR5K_DESC_TX_STATUS1_DONE 0x00000001
406#define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe 273#define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe
407#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1 274#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1
@@ -411,8 +278,6 @@ struct ath5k_hw_tx_status {
411#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S 21 278#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S 21
412#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS 0x00800000 279#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS 0x00800000
413#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA 0x01000000 280#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA 0x01000000
414} __packed;
415
416 281
417/* 282/*
418 * 5210/5211 hardware TX descriptor 283 * 5210/5211 hardware TX descriptor
@@ -441,176 +306,27 @@ struct ath5k_hw_all_rx_desc {
441 } u; 306 } u;
442} __packed; 307} __packed;
443 308
444
445/* 309/*
446 * AR5K REGISTER ACCESS 310 * Atheros hardware descriptor
311 * This is read and written to by the hardware
447 */ 312 */
313struct ath5k_desc {
314 u32 ds_link; /* physical address of the next descriptor */
315 u32 ds_data; /* physical address of data buffer (skb) */
448 316
449/*Swap RX/TX Descriptor for big endian archs*/ 317 union {
450#if defined(__BIG_ENDIAN) 318 struct ath5k_hw_5210_tx_desc ds_tx5210;
451#define AR5K_INIT_CFG ( \ 319 struct ath5k_hw_5212_tx_desc ds_tx5212;
452 AR5K_CFG_SWTD | AR5K_CFG_SWRD \ 320 struct ath5k_hw_all_rx_desc ds_rx;
453) 321 } ud;
454#else 322} __packed;
455#define AR5K_INIT_CFG 0x00000000
456#endif
457
458/*#define AR5K_REG_READ(_reg) ath5k_hw_reg_read(ah, _reg)
459
460#define AR5K_REG_WRITE(_reg, _val) ath5k_hw_reg_write(ah, _val, _reg)*/
461
462#define AR5K_REG_SM(_val, _flags) \
463 (((_val) << _flags##_S) & (_flags))
464
465#define AR5K_REG_MS(_val, _flags) \
466 (((_val) & (_flags)) >> _flags##_S)
467
468/* Some registers can hold multiple values of interest. For this
469 * reason when we want to write to these registers we must first
470 * retrieve the values which we do not want to clear (lets call this
471 * old_data) and then set the register with this and our new_value:
472 * ( old_data | new_value) */
473#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val) \
474 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \
475 (((_val) << _flags##_S) & (_flags)), _reg)
476
477#define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask) \
478 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & \
479 (_mask)) | (_flags), _reg)
480
481#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags) \
482 ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg)
483
484#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \
485 ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg)
486
487#define AR5K_PHY_WRITE(ah, _reg, _val) \
488 ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
489
490#define AR5K_PHY_READ(ah, _reg) \
491 ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
492
493#define AR5K_REG_WAIT(_i) do { \
494 if (_i % 64) \
495 udelay(1); \
496} while (0)
497
498#define AR5K_EEPROM_READ(_o, _v) do { \
499 if ((ret = ath5k_hw_eeprom_read(ah, (_o), &(_v))) != 0) \
500 return (ret); \
501} while (0)
502
503#define AR5K_EEPROM_READ_HDR(_o, _v) \
504 AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \
505
506/* Read status of selected queue */
507#define AR5K_REG_READ_Q(ah, _reg, _queue) \
508 (ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \
509
510#define AR5K_REG_WRITE_Q(ah, _reg, _queue) \
511 ath5k_hw_reg_write(ah, (1 << _queue), _reg)
512
513#define AR5K_Q_ENABLE_BITS(_reg, _queue) do { \
514 _reg |= 1 << _queue; \
515} while (0)
516
517#define AR5K_Q_DISABLE_BITS(_reg, _queue) do { \
518 _reg &= ~(1 << _queue); \
519} while (0)
520
521#define AR5K_LOW_ID(_a)( \
522(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
523)
524
525#define AR5K_HIGH_ID(_a) ((_a)[4] | (_a)[5] << 8)
526
527/*
528 * Initial register values
529 */
530
531/*
532 * Common initial register values
533 */
534#define AR5K_INIT_MODE CHANNEL_B
535
536#define AR5K_INIT_TX_LATENCY 502
537#define AR5K_INIT_USEC 39
538#define AR5K_INIT_USEC_TURBO 79
539#define AR5K_INIT_USEC_32 31
540#define AR5K_INIT_CARR_SENSE_EN 1
541#define AR5K_INIT_PROG_IFS 920
542#define AR5K_INIT_PROG_IFS_TURBO 960
543#define AR5K_INIT_EIFS 3440
544#define AR5K_INIT_EIFS_TURBO 6880
545#define AR5K_INIT_SLOT_TIME 396
546#define AR5K_INIT_SLOT_TIME_TURBO 480
547#define AR5K_INIT_ACK_CTS_TIMEOUT 1024
548#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800
549#define AR5K_INIT_SIFS 560
550#define AR5K_INIT_SIFS_TURBO 480
551#define AR5K_INIT_SH_RETRY 10
552#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY
553#define AR5K_INIT_SSH_RETRY 32
554#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY
555#define AR5K_INIT_TX_RETRY 10
556#define AR5K_INIT_TOPS 8
557#define AR5K_INIT_RXNOFRM 8
558#define AR5K_INIT_RPGTO 0
559#define AR5K_INIT_TXNOFRM 0
560#define AR5K_INIT_BEACON_PERIOD 65535
561#define AR5K_INIT_TIM_OFFSET 0
562#define AR5K_INIT_BEACON_EN 0
563#define AR5K_INIT_RESET_TSF 0
564
565#define AR5K_INIT_TRANSMIT_LATENCY ( \
566 (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
567 (AR5K_INIT_USEC) \
568)
569#define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \
570 (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
571 (AR5K_INIT_USEC_TURBO) \
572)
573#define AR5K_INIT_PROTO_TIME_CNTRL ( \
574 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \
575 (AR5K_INIT_PROG_IFS) \
576)
577#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \
578 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
579 (AR5K_INIT_PROG_IFS_TURBO) \
580)
581#define AR5K_INIT_BEACON_CONTROL ( \
582 (AR5K_INIT_RESET_TSF << 24) | (AR5K_INIT_BEACON_EN << 23) | \
583 (AR5K_INIT_TIM_OFFSET << 16) | (AR5K_INIT_BEACON_PERIOD) \
584)
585
586/*
587 * Non-common initial register values which have to be loaded into the
588 * card at boot time and after each reset.
589 */
590
591/* Register dumps are done per operation mode */
592#define AR5K_INI_RFGAIN_5GHZ 0
593#define AR5K_INI_RFGAIN_2GHZ 1
594
595#define AR5K_INI_VAL_11A 0
596#define AR5K_INI_VAL_11A_TURBO 1
597#define AR5K_INI_VAL_11B 2
598#define AR5K_INI_VAL_11G 3
599#define AR5K_INI_VAL_11G_TURBO 4
600#define AR5K_INI_VAL_XR 0
601#define AR5K_INI_VAL_MAX 5
602
603#define AR5K_RF5111_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
604#define AR5K_RF5112_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
605 323
606static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) 324#define AR5K_RXDESC_INTREQ 0x0020
607{
608 u32 retval = 0, bit, i;
609 325
610 for (i = 0; i < bits; i++) { 326#define AR5K_TXDESC_CLRDMASK 0x0001
611 bit = (val >> i) & 1; 327#define AR5K_TXDESC_NOACK 0x0002 /*[5211+]*/
612 retval = (retval << 1) | bit; 328#define AR5K_TXDESC_RTSENA 0x0004
613 } 329#define AR5K_TXDESC_CTSENA 0x0008
330#define AR5K_TXDESC_INTREQ 0x0010
331#define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/
614 332
615 return retval;
616}
diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath5k/dma.c
new file mode 100644
index 000000000000..a28090be9603
--- /dev/null
+++ b/drivers/net/wireless/ath5k/dma.c
@@ -0,0 +1,566 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 */
18
19/*************************************\
20* DMA and interrupt masking functions *
21\*************************************/
22
23/*
24 * dma.c - DMA and interrupt masking functions
25 *
26 * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and
27 * handle queue setup for 5210 chipset (rest are handled on qcu.c).
28 * Also we setup interrupt mask register (IMR) and read the various iterrupt
29 * status registers (ISR).
30 *
31 * TODO: Handle SISR on 5211+ and introduce a function to return the queue
32 * number that resulted the interrupt.
33 */
34
35#include "ath5k.h"
36#include "reg.h"
37#include "debug.h"
38#include "base.h"
39
40/*********\
41* Receive *
42\*********/
43
44/**
45 * ath5k_hw_start_rx_dma - Start DMA receive
46 *
47 * @ah: The &struct ath5k_hw
48 */
49void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
50{
51 ATH5K_TRACE(ah->ah_sc);
52 ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
53 ath5k_hw_reg_read(ah, AR5K_CR);
54}
55
56/**
57 * ath5k_hw_stop_rx_dma - Stop DMA receive
58 *
59 * @ah: The &struct ath5k_hw
60 */
61int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
62{
63 unsigned int i;
64
65 ATH5K_TRACE(ah->ah_sc);
66 ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
67
68 /*
69 * It may take some time to disable the DMA receive unit
70 */
71 for (i = 2000; i > 0 &&
72 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
73 i--)
74 udelay(10);
75
76 return i ? 0 : -EBUSY;
77}
78
79/**
80 * ath5k_hw_get_rxdp - Get RX Descriptor's address
81 *
82 * @ah: The &struct ath5k_hw
83 *
84 * XXX: Is RXDP read and clear ?
85 */
86u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
87{
88 return ath5k_hw_reg_read(ah, AR5K_RXDP);
89}
90
91/**
92 * ath5k_hw_set_rxdp - Set RX Descriptor's address
93 *
94 * @ah: The &struct ath5k_hw
95 * @phys_addr: RX descriptor address
96 *
97 * XXX: Should we check if rx is enabled before setting rxdp ?
98 */
99void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
100{
101 ATH5K_TRACE(ah->ah_sc);
102
103 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
104}
105
106
107/**********\
108* Transmit *
109\**********/
110
111/**
112 * ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue
113 *
114 * @ah: The &struct ath5k_hw
115 * @queue: The hw queue number
116 *
117 * Start DMA transmit for a specific queue and since 5210 doesn't have
118 * QCU/DCU, set up queue parameters for 5210 here based on queue type (one
119 * queue for normal data and one queue for beacons). For queue setup
120 * on newer chips check out qcu.c. Returns -EINVAL if queue number is out
121 * of range or if queue is already disabled.
122 *
123 * NOTE: Must be called after setting up tx control descriptor for that
124 * queue (see below).
125 */
126int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
127{
128 u32 tx_queue;
129
130 ATH5K_TRACE(ah->ah_sc);
131 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
132
133 /* Return if queue is declared inactive */
134 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
135 return -EIO;
136
137 if (ah->ah_version == AR5K_AR5210) {
138 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
139
140 /*
141 * Set the queue by type on 5210
142 */
143 switch (ah->ah_txq[queue].tqi_type) {
144 case AR5K_TX_QUEUE_DATA:
145 tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
146 break;
147 case AR5K_TX_QUEUE_BEACON:
148 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
149 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
150 AR5K_BSR);
151 break;
152 case AR5K_TX_QUEUE_CAB:
153 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
154 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
155 AR5K_BCR_BDMAE, AR5K_BSR);
156 break;
157 default:
158 return -EINVAL;
159 }
160 /* Start queue */
161 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
162 ath5k_hw_reg_read(ah, AR5K_CR);
163 } else {
164 /* Return if queue is disabled */
165 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
166 return -EIO;
167
168 /* Start queue */
169 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
170 }
171
172 return 0;
173}
174
175/**
176 * ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue
177 *
178 * @ah: The &struct ath5k_hw
179 * @queue: The hw queue number
180 *
181 * Stop DMA transmit on a specific hw queue and drain queue so we don't
182 * have any pending frames. Returns -EBUSY if we still have pending frames,
183 * -EINVAL if queue number is out of range.
184 *
185 * TODO: Test queue drain code
186 */
187int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
188{
189 unsigned int i = 100;
190 u32 tx_queue, pending;
191
192 ATH5K_TRACE(ah->ah_sc);
193 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
194
195 /* Return if queue is declared inactive */
196 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
197 return -EIO;
198
199 if (ah->ah_version == AR5K_AR5210) {
200 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
201
202 /*
203 * Set by queue type
204 */
205 switch (ah->ah_txq[queue].tqi_type) {
206 case AR5K_TX_QUEUE_DATA:
207 tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
208 break;
209 case AR5K_TX_QUEUE_BEACON:
210 case AR5K_TX_QUEUE_CAB:
211 /* XXX Fix me... */
212 tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
213 ath5k_hw_reg_write(ah, 0, AR5K_BSR);
214 break;
215 default:
216 return -EINVAL;
217 }
218
219 /* Stop queue */
220 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
221 ath5k_hw_reg_read(ah, AR5K_CR);
222 } else {
223 /*
224 * Schedule TX disable and wait until queue is empty
225 */
226 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
227
228 /*Check for pending frames*/
229 do {
230 pending = ath5k_hw_reg_read(ah,
231 AR5K_QUEUE_STATUS(queue)) &
232 AR5K_QCU_STS_FRMPENDCNT;
233 udelay(100);
234 } while (--i && pending);
235
236 /* Clear register */
237 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
238 if (pending)
239 return -EBUSY;
240 }
241
242 /* TODO: Check for success else return error */
243 return 0;
244}
245
246/**
247 * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
248 *
249 * @ah: The &struct ath5k_hw
250 * @queue: The hw queue number
251 *
252 * Get TX descriptor's address for a specific queue. For 5210 we ignore
253 * the queue number and use tx queue type since we only have 2 queues.
254 * We use TXDP0 for normal data queue and TXDP1 for beacon queue.
255 * For newer chips with QCU/DCU we just read the corresponding TXDP register.
256 *
257 * XXX: Is TXDP read and clear ?
258 */
259u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue)
260{
261 u16 tx_reg;
262
263 ATH5K_TRACE(ah->ah_sc);
264 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
265
266 /*
267 * Get the transmit queue descriptor pointer from the selected queue
268 */
269 /*5210 doesn't have QCU*/
270 if (ah->ah_version == AR5K_AR5210) {
271 switch (ah->ah_txq[queue].tqi_type) {
272 case AR5K_TX_QUEUE_DATA:
273 tx_reg = AR5K_NOQCU_TXDP0;
274 break;
275 case AR5K_TX_QUEUE_BEACON:
276 case AR5K_TX_QUEUE_CAB:
277 tx_reg = AR5K_NOQCU_TXDP1;
278 break;
279 default:
280 return 0xffffffff;
281 }
282 } else {
283 tx_reg = AR5K_QUEUE_TXDP(queue);
284 }
285
286 return ath5k_hw_reg_read(ah, tx_reg);
287}
288
289/**
290 * ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue
291 *
292 * @ah: The &struct ath5k_hw
293 * @queue: The hw queue number
294 *
295 * Set TX descriptor's address for a specific queue. For 5210 we ignore
296 * the queue number and we use tx queue type since we only have 2 queues
297 * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue.
298 * For newer chips with QCU/DCU we just set the corresponding TXDP register.
299 * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still
300 * active.
301 */
302int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
303{
304 u16 tx_reg;
305
306 ATH5K_TRACE(ah->ah_sc);
307 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
308
309 /*
310 * Set the transmit queue descriptor pointer register by type
311 * on 5210
312 */
313 if (ah->ah_version == AR5K_AR5210) {
314 switch (ah->ah_txq[queue].tqi_type) {
315 case AR5K_TX_QUEUE_DATA:
316 tx_reg = AR5K_NOQCU_TXDP0;
317 break;
318 case AR5K_TX_QUEUE_BEACON:
319 case AR5K_TX_QUEUE_CAB:
320 tx_reg = AR5K_NOQCU_TXDP1;
321 break;
322 default:
323 return -EINVAL;
324 }
325 } else {
326 /*
327 * Set the transmit queue descriptor pointer for
328 * the selected queue on QCU for 5211+
329 * (this won't work if the queue is still active)
330 */
331 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
332 return -EIO;
333
334 tx_reg = AR5K_QUEUE_TXDP(queue);
335 }
336
337 /* Set descriptor pointer */
338 ath5k_hw_reg_write(ah, phys_addr, tx_reg);
339
340 return 0;
341}
342
343/**
344 * ath5k_hw_update_tx_triglevel - Update tx trigger level
345 *
346 * @ah: The &struct ath5k_hw
347 * @increase: Flag to force increase of trigger level
348 *
349 * This function increases/decreases the tx trigger level for the tx fifo
350 * buffer (aka FIFO threshold) that is used to indicate when PCU flushes
351 * the buffer and transmits it's data. Lowering this results sending small
352 * frames more quickly but can lead to tx underruns, raising it a lot can
353 * result other problems (i think bmiss is related). Right now we start with
354 * the lowest possible (64Bytes) and if we get tx underrun we increase it using
355 * the increase flag. Returns -EIO if we have have reached maximum/minimum.
356 *
357 * XXX: Link this with tx DMA size ?
358 * XXX: Use it to save interrupts ?
359 * TODO: Needs testing, i think it's related to bmiss...
360 */
361int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
362{
363 u32 trigger_level, imr;
364 int ret = -EIO;
365
366 ATH5K_TRACE(ah->ah_sc);
367
368 /*
369 * Disable interrupts by setting the mask
370 */
371 imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
372
373 trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
374 AR5K_TXCFG_TXFULL);
375
376 if (!increase) {
377 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
378 goto done;
379 } else
380 trigger_level +=
381 ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
382
383 /*
384 * Update trigger level on success
385 */
386 if (ah->ah_version == AR5K_AR5210)
387 ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
388 else
389 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
390 AR5K_TXCFG_TXFULL, trigger_level);
391
392 ret = 0;
393
394done:
395 /*
396 * Restore interrupt mask
397 */
398 ath5k_hw_set_imr(ah, imr);
399
400 return ret;
401}
402
403/*******************\
404* Interrupt masking *
405\*******************/
406
407/**
408 * ath5k_hw_is_intr_pending - Check if we have pending interrupts
409 *
410 * @ah: The &struct ath5k_hw
411 *
412 * Check if we have pending interrupts to process. Returns 1 if we
413 * have pending interrupts and 0 if we haven't.
414 */
415bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
416{
417 ATH5K_TRACE(ah->ah_sc);
418 return ath5k_hw_reg_read(ah, AR5K_INTPEND);
419}
420
421/**
422 * ath5k_hw_get_isr - Get interrupt status
423 *
424 * @ah: The @struct ath5k_hw
425 * @interrupt_mask: Driver's interrupt mask used to filter out
426 * interrupts in sw.
427 *
428 * This function is used inside our interrupt handler to determine the reason
429 * for the interrupt by reading Primary Interrupt Status Register. Returns an
430 * abstract interrupt status mask which is mostly ISR with some uncommon bits
431 * being mapped on some standard non hw-specific positions
432 * (check out &ath5k_int).
433 *
434 * NOTE: We use read-and-clear register, so after this function is called ISR
435 * is zeroed.
436 *
437 * XXX: Why filter interrupts in sw with interrupt_mask ? No benefit at all
438 * plus it can be misleading (one might thing that we save interrupts this way)
439 */
440int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
441{
442 u32 data;
443
444 ATH5K_TRACE(ah->ah_sc);
445
446 /*
447 * Read interrupt status from the Interrupt Status register
448 * on 5210
449 */
450 if (ah->ah_version == AR5K_AR5210) {
451 data = ath5k_hw_reg_read(ah, AR5K_ISR);
452 if (unlikely(data == AR5K_INT_NOCARD)) {
453 *interrupt_mask = data;
454 return -ENODEV;
455 }
456 } else {
457 /*
458 * Read interrupt status from the Read-And-Clear
459 * shadow register.
460 * Note: PISR/SISR Not available on 5210
461 */
462 data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
463 }
464
465 /*
466 * Get abstract interrupt mask (driver-compatible)
467 */
468 *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
469
470 if (unlikely(data == AR5K_INT_NOCARD))
471 return -ENODEV;
472
473 if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR))
474 *interrupt_mask |= AR5K_INT_RX;
475
476 if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR
477 | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL))
478 *interrupt_mask |= AR5K_INT_TX;
479
480 if (ah->ah_version != AR5K_AR5210) {
481 /*HIU = Host Interface Unit (PCI etc)*/
482 if (unlikely(data & (AR5K_ISR_HIUERR)))
483 *interrupt_mask |= AR5K_INT_FATAL;
484
485 /*Beacon Not Ready*/
486 if (unlikely(data & (AR5K_ISR_BNR)))
487 *interrupt_mask |= AR5K_INT_BNR;
488 }
489
490 /*
491 * XXX: BMISS interrupts may occur after association.
492 * I found this on 5210 code but it needs testing. If this is
493 * true we should disable them before assoc and re-enable them
494 * after a successfull assoc + some jiffies.
495 */
496#if 0
497 interrupt_mask &= ~AR5K_INT_BMISS;
498#endif
499
500 /*
501 * In case we didn't handle anything,
502 * print the register value.
503 */
504 if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
505 ATH5K_PRINTF("0x%08x\n", data);
506
507 return 0;
508}
509
510/**
511 * ath5k_hw_set_imr - Set interrupt mask
512 *
513 * @ah: The &struct ath5k_hw
514 * @new_mask: The new interrupt mask to be set
515 *
516 * Set the interrupt mask in hw to save interrupts. We do that by mapping
517 * ath5k_int bits to hw-specific bits to remove abstraction and writing
518 * Interrupt Mask Register.
519 */
520enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
521{
522 enum ath5k_int old_mask, int_mask;
523
524 /*
525 * Disable card interrupts to prevent any race conditions
526 * (they will be re-enabled afterwards).
527 */
528 ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
529 ath5k_hw_reg_read(ah, AR5K_IER);
530
531 old_mask = ah->ah_imr;
532
533 /*
534 * Add additional, chipset-dependent interrupt mask flags
535 * and write them to the IMR (interrupt mask register).
536 */
537 int_mask = new_mask & AR5K_INT_COMMON;
538
539 if (new_mask & AR5K_INT_RX)
540 int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN |
541 AR5K_IMR_RXDESC;
542
543 if (new_mask & AR5K_INT_TX)
544 int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC |
545 AR5K_IMR_TXURN;
546
547 if (ah->ah_version != AR5K_AR5210) {
548 if (new_mask & AR5K_INT_FATAL) {
549 int_mask |= AR5K_IMR_HIUERR;
550 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT |
551 AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR);
552 }
553 }
554
555 ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
556
557 /* Store new interrupt mask */
558 ah->ah_imr = new_mask;
559
560 /* ..re-enable interrupts */
561 ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
562 ath5k_hw_reg_read(ah, AR5K_IER);
563
564 return old_mask;
565}
566
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c
new file mode 100644
index 000000000000..a883839b6a9f
--- /dev/null
+++ b/drivers/net/wireless/ath5k/eeprom.c
@@ -0,0 +1,466 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 */
18
19/*************************************\
20* EEPROM access functions and helpers *
21\*************************************/
22
23#include "ath5k.h"
24#include "reg.h"
25#include "debug.h"
26#include "base.h"
27
28/*
29 * Read from eeprom
30 */
31static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
32{
33 u32 status, timeout;
34
35 ATH5K_TRACE(ah->ah_sc);
36 /*
37 * Initialize EEPROM access
38 */
39 if (ah->ah_version == AR5K_AR5210) {
40 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
41 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
42 } else {
43 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
44 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
45 AR5K_EEPROM_CMD_READ);
46 }
47
48 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
49 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
50 if (status & AR5K_EEPROM_STAT_RDDONE) {
51 if (status & AR5K_EEPROM_STAT_RDERR)
52 return -EIO;
53 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
54 0xffff);
55 return 0;
56 }
57 udelay(15);
58 }
59
60 return -ETIMEDOUT;
61}
62
63/*
64 * Translate binary channel representation in EEPROM to frequency
65 */
66static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin,
67 unsigned int mode)
68{
69 u16 val;
70
71 if (bin == AR5K_EEPROM_CHANNEL_DIS)
72 return bin;
73
74 if (mode == AR5K_EEPROM_MODE_11A) {
75 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
76 val = (5 * bin) + 4800;
77 else
78 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
79 (bin * 10) + 5100;
80 } else {
81 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
82 val = bin + 2300;
83 else
84 val = bin + 2400;
85 }
86
87 return val;
88}
89
90/*
91 * Read antenna infos from eeprom
92 */
93static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
94 unsigned int mode)
95{
96 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
97 u32 o = *offset;
98 u16 val;
99 int ret, i = 0;
100
101 AR5K_EEPROM_READ(o++, val);
102 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
103 ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f;
104 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
105
106 AR5K_EEPROM_READ(o++, val);
107 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
108 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
109 ee->ee_ant_control[mode][i++] = val & 0x3f;
110
111 AR5K_EEPROM_READ(o++, val);
112 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
113 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
114 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
115
116 AR5K_EEPROM_READ(o++, val);
117 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
118 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
119 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
120 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
121
122 AR5K_EEPROM_READ(o++, val);
123 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
124 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
125 ee->ee_ant_control[mode][i++] = val & 0x3f;
126
127 /* Get antenna modes */
128 ah->ah_antenna[mode][0] =
129 (ee->ee_ant_control[mode][0] << 4) | 0x1;
130 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
131 ee->ee_ant_control[mode][1] |
132 (ee->ee_ant_control[mode][2] << 6) |
133 (ee->ee_ant_control[mode][3] << 12) |
134 (ee->ee_ant_control[mode][4] << 18) |
135 (ee->ee_ant_control[mode][5] << 24);
136 ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
137 ee->ee_ant_control[mode][6] |
138 (ee->ee_ant_control[mode][7] << 6) |
139 (ee->ee_ant_control[mode][8] << 12) |
140 (ee->ee_ant_control[mode][9] << 18) |
141 (ee->ee_ant_control[mode][10] << 24);
142
143 /* return new offset */
144 *offset = o;
145
146 return 0;
147}
148
149/*
150 * Read supported modes from eeprom
151 */
152static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
153 unsigned int mode)
154{
155 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
156 u32 o = *offset;
157 u16 val;
158 int ret;
159
160 AR5K_EEPROM_READ(o++, val);
161 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
162 ee->ee_thr_62[mode] = val & 0xff;
163
164 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
165 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
166
167 AR5K_EEPROM_READ(o++, val);
168 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
169 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
170
171 AR5K_EEPROM_READ(o++, val);
172 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
173
174 if ((val & 0xff) & 0x80)
175 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
176 else
177 ee->ee_noise_floor_thr[mode] = val & 0xff;
178
179 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
180 ee->ee_noise_floor_thr[mode] =
181 mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
182
183 AR5K_EEPROM_READ(o++, val);
184 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
185 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
186 ee->ee_xpd[mode] = val & 0x1;
187
188 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
189 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
190
191 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
192 AR5K_EEPROM_READ(o++, val);
193 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
194
195 if (mode == AR5K_EEPROM_MODE_11A)
196 ee->ee_xr_power[mode] = val & 0x3f;
197 else {
198 ee->ee_ob[mode][0] = val & 0x7;
199 ee->ee_db[mode][0] = (val >> 3) & 0x7;
200 }
201 }
202
203 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
204 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
205 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
206 } else {
207 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
208
209 AR5K_EEPROM_READ(o++, val);
210 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
211
212 if (mode == AR5K_EEPROM_MODE_11G)
213 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
214 }
215
216 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
217 mode == AR5K_EEPROM_MODE_11A) {
218 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
219 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
220 }
221
222 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
223 mode == AR5K_EEPROM_MODE_11G)
224 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
225
226 /* return new offset */
227 *offset = o;
228
229 return 0;
230}
231
232/*
233 * Initialize eeprom & capabilities structs
234 */
235int ath5k_eeprom_init(struct ath5k_hw *ah)
236{
237 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
238 unsigned int mode, i;
239 int ret;
240 u32 offset;
241 u16 val;
242
243 /* Initial TX thermal adjustment values */
244 ee->ee_tx_clip = 4;
245 ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
246 ee->ee_gain_select = 1;
247
248 /*
249 * Read values from EEPROM and store them in the capability structure
250 */
251 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
252 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
253 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
254 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
255 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
256
257 /* Return if we have an old EEPROM */
258 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
259 return 0;
260
261#ifdef notyet
262 /*
263 * Validate the checksum of the EEPROM date. There are some
264 * devices with invalid EEPROMs.
265 */
266 for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
267 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
268 cksum ^= val;
269 }
270 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
271 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
272 return -EIO;
273 }
274#endif
275
276 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
277 ee_ant_gain);
278
279 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
280 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
281 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
282 }
283
284 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
285 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
286 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
287 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
288
289 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
290 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
291 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
292 }
293
294 /*
295 * Get conformance test limit values
296 */
297 offset = AR5K_EEPROM_CTL(ah->ah_ee_version);
298 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version);
299
300 for (i = 0; i < ee->ee_ctls; i++) {
301 AR5K_EEPROM_READ(offset++, val);
302 ee->ee_ctl[i] = (val >> 8) & 0xff;
303 ee->ee_ctl[i + 1] = val & 0xff;
304 }
305
306 /*
307 * Get values for 802.11a (5GHz)
308 */
309 mode = AR5K_EEPROM_MODE_11A;
310
311 ee->ee_turbo_max_power[mode] =
312 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
313
314 offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
315
316 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
317 if (ret)
318 return ret;
319
320 AR5K_EEPROM_READ(offset++, val);
321 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
322 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
323 ee->ee_db[mode][3] = (val >> 2) & 0x7;
324 ee->ee_ob[mode][2] = (val << 1) & 0x7;
325
326 AR5K_EEPROM_READ(offset++, val);
327 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
328 ee->ee_db[mode][2] = (val >> 12) & 0x7;
329 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
330 ee->ee_db[mode][1] = (val >> 6) & 0x7;
331 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
332 ee->ee_db[mode][0] = val & 0x7;
333
334 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
335 if (ret)
336 return ret;
337
338 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
339 AR5K_EEPROM_READ(offset++, val);
340 ee->ee_margin_tx_rx[mode] = val & 0x3f;
341 }
342
343 /*
344 * Get values for 802.11b (2.4GHz)
345 */
346 mode = AR5K_EEPROM_MODE_11B;
347 offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
348
349 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
350 if (ret)
351 return ret;
352
353 AR5K_EEPROM_READ(offset++, val);
354 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
355 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
356 ee->ee_db[mode][1] = val & 0x7;
357
358 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
359 if (ret)
360 return ret;
361
362 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
363 AR5K_EEPROM_READ(offset++, val);
364 ee->ee_cal_pier[mode][0] =
365 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
366 ee->ee_cal_pier[mode][1] =
367 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
368
369 AR5K_EEPROM_READ(offset++, val);
370 ee->ee_cal_pier[mode][2] =
371 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
372 }
373
374 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
375 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
376
377 /*
378 * Get values for 802.11g (2.4GHz)
379 */
380 mode = AR5K_EEPROM_MODE_11G;
381 offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
382
383 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
384 if (ret)
385 return ret;
386
387 AR5K_EEPROM_READ(offset++, val);
388 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
389 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
390 ee->ee_db[mode][1] = val & 0x7;
391
392 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
393 if (ret)
394 return ret;
395
396 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
397 AR5K_EEPROM_READ(offset++, val);
398 ee->ee_cal_pier[mode][0] =
399 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
400 ee->ee_cal_pier[mode][1] =
401 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
402
403 AR5K_EEPROM_READ(offset++, val);
404 ee->ee_turbo_max_power[mode] = val & 0x7f;
405 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
406
407 AR5K_EEPROM_READ(offset++, val);
408 ee->ee_cal_pier[mode][2] =
409 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
410
411 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
412 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
413
414 AR5K_EEPROM_READ(offset++, val);
415 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
416 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
417
418 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
419 AR5K_EEPROM_READ(offset++, val);
420 ee->ee_cck_ofdm_gain_delta = val & 0xff;
421 }
422 }
423
424 /*
425 * Read 5GHz EEPROM channels
426 */
427
428 return 0;
429}
430
431/*
432 * Read the MAC address from eeprom
433 */
434int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
435{
436 u8 mac_d[ETH_ALEN];
437 u32 total, offset;
438 u16 data;
439 int octet, ret;
440
441 memset(mac, 0, ETH_ALEN);
442 memset(mac_d, 0, ETH_ALEN);
443
444 ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
445 if (ret)
446 return ret;
447
448 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
449 ret = ath5k_hw_eeprom_read(ah, offset, &data);
450 if (ret)
451 return ret;
452
453 total += data;
454 mac_d[octet + 1] = data & 0xff;
455 mac_d[octet] = data >> 8;
456 octet += 2;
457 }
458
459 memcpy(mac, mac_d, ETH_ALEN);
460
461 if (!total || total == 3 * 0xffff)
462 return -EINVAL;
463
464 return 0;
465}
466
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h
new file mode 100644
index 000000000000..a468ecfbb18a
--- /dev/null
+++ b/drivers/net/wireless/ath5k/eeprom.h
@@ -0,0 +1,215 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 */
18
19/*
20 * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
21 */
22#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
23#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
24#define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
25#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
26#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
27
28#define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */
29#define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */
30#define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */
31#define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */
32#define AR5K_EEPROM_PROTECT_WR_32_63 0x0008
33#define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */
34#define AR5K_EEPROM_PROTECT_WR_64_127 0x0020
35#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */
36#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
37#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */
38#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
39#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */
40#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
41#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */
42#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
43#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */
44#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
45#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
46#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
47#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
48#define AR5K_EEPROM_INFO_CKSUM 0xffff
49#define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n))
50
51#define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */
52#define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */
53#define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */
54#define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */
55#define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
56#define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */
57#define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
58#define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */
59#define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */
60#define AR5K_EEPROM_VERSION_4_3 0x4003
61#define AR5K_EEPROM_VERSION_4_4 0x4004
62#define AR5K_EEPROM_VERSION_4_5 0x4005
63#define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */
64#define AR5K_EEPROM_VERSION_4_7 0x4007
65
66#define AR5K_EEPROM_MODE_11A 0
67#define AR5K_EEPROM_MODE_11B 1
68#define AR5K_EEPROM_MODE_11G 2
69
70#define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */
71#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
72#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
73#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
74#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */
75#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */
76#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7)
77#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz (?) */
78#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
79
80#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
81#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
82#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
83#define AR5K_EEPROM_RFKILL_POLARITY_S 1
84
85/* Newer EEPROMs are using a different offset */
86#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
87 (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
88
89#define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
90#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((int8_t)(((_v) >> 8) & 0xff))
91#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff))
92
93/* calibration settings */
94#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
95#define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
96#define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
97#define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */
98
99/* [3.1 - 3.3] */
100#define AR5K_EEPROM_OBDB0_2GHZ 0x00ec
101#define AR5K_EEPROM_OBDB1_2GHZ 0x00ed
102
103/* Misc values available since EEPROM 4.0 */
104#define AR5K_EEPROM_MISC0 0x00c4
105#define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff)
106#define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3)
107#define AR5K_EEPROM_MISC1 0x00c5
108#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
109#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1)
110
111
112/* Some EEPROM defines */
113#define AR5K_EEPROM_EEP_SCALE 100
114#define AR5K_EEPROM_EEP_DELTA 10
115#define AR5K_EEPROM_N_MODES 3
116#define AR5K_EEPROM_N_5GHZ_CHAN 10
117#define AR5K_EEPROM_N_2GHZ_CHAN 3
118#define AR5K_EEPROM_MAX_CHAN 10
119#define AR5K_EEPROM_N_PCDAC 11
120#define AR5K_EEPROM_N_TEST_FREQ 8
121#define AR5K_EEPROM_N_EDGES 8
122#define AR5K_EEPROM_N_INTERCEPTS 11
123#define AR5K_EEPROM_FREQ_M(_v) AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
124#define AR5K_EEPROM_PCDAC_M 0x3f
125#define AR5K_EEPROM_PCDAC_START 1
126#define AR5K_EEPROM_PCDAC_STOP 63
127#define AR5K_EEPROM_PCDAC_STEP 1
128#define AR5K_EEPROM_NON_EDGE_M 0x40
129#define AR5K_EEPROM_CHANNEL_POWER 8
130#define AR5K_EEPROM_N_OBDB 4
131#define AR5K_EEPROM_OBDB_DIS 0xffff
132#define AR5K_EEPROM_CHANNEL_DIS 0xff
133#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
134#define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32)
135#define AR5K_EEPROM_MAX_CTLS 32
136#define AR5K_EEPROM_N_XPD_PER_CHANNEL 4
137#define AR5K_EEPROM_N_XPD0_POINTS 4
138#define AR5K_EEPROM_N_XPD3_POINTS 3
139#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35
140#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55
141#define AR5K_EEPROM_POWER_M 0x3f
142#define AR5K_EEPROM_POWER_MIN 0
143#define AR5K_EEPROM_POWER_MAX 3150
144#define AR5K_EEPROM_POWER_STEP 50
145#define AR5K_EEPROM_POWER_TABLE_SIZE 64
146#define AR5K_EEPROM_N_POWER_LOC_11B 4
147#define AR5K_EEPROM_N_POWER_LOC_11G 6
148#define AR5K_EEPROM_I_GAIN 10
149#define AR5K_EEPROM_CCK_OFDM_DELTA 15
150#define AR5K_EEPROM_N_IQ_CAL 2
151
152#define AR5K_EEPROM_READ(_o, _v) do { \
153 ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \
154 if (ret) \
155 return ret; \
156} while (0)
157
158#define AR5K_EEPROM_READ_HDR(_o, _v) \
159 AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \
160
161/* Struct to hold EEPROM calibration data */
162struct ath5k_eeprom_info {
163 u16 ee_magic;
164 u16 ee_protect;
165 u16 ee_regdomain;
166 u16 ee_version;
167 u16 ee_header;
168 u16 ee_ant_gain;
169 u16 ee_misc0;
170 u16 ee_misc1;
171 u16 ee_cck_ofdm_gain_delta;
172 u16 ee_cck_ofdm_power_delta;
173 u16 ee_scaled_cck_delta;
174
175 /* Used for tx thermal adjustment (eeprom_init, rfregs) */
176 u16 ee_tx_clip;
177 u16 ee_pwd_84;
178 u16 ee_pwd_90;
179 u16 ee_gain_select;
180
181 /* RF Calibration settings (reset, rfregs) */
182 u16 ee_i_cal[AR5K_EEPROM_N_MODES];
183 u16 ee_q_cal[AR5K_EEPROM_N_MODES];
184 u16 ee_fixed_bias[AR5K_EEPROM_N_MODES];
185 u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES];
186 u16 ee_xr_power[AR5K_EEPROM_N_MODES];
187 u16 ee_switch_settling[AR5K_EEPROM_N_MODES];
188 u16 ee_ant_tx_rx[AR5K_EEPROM_N_MODES];
189 u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
190 u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
191 u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
192 u16 ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
193 u16 ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
194 u16 ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
195 u16 ee_thr_62[AR5K_EEPROM_N_MODES];
196 u16 ee_xlna_gain[AR5K_EEPROM_N_MODES];
197 u16 ee_xpd[AR5K_EEPROM_N_MODES];
198 u16 ee_x_gain[AR5K_EEPROM_N_MODES];
199 u16 ee_i_gain[AR5K_EEPROM_N_MODES];
200 u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
201
202 /* Unused */
203 u16 ee_false_detect[AR5K_EEPROM_N_MODES];
204 u16 ee_cal_pier[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_2GHZ_CHAN];
205 u16 ee_channel[AR5K_EEPROM_N_MODES][AR5K_EEPROM_MAX_CHAN]; /*empty*/
206
207 /* Conformance test limits (Unused) */
208 u16 ee_ctls;
209 u16 ee_ctl[AR5K_EEPROM_MAX_CTLS];
210
211 /* Noise Floor Calibration settings */
212 s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
213 s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES];
214 s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES];
215};
diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath5k/gpio.c
new file mode 100644
index 000000000000..b77205adc180
--- /dev/null
+++ b/drivers/net/wireless/ath5k/gpio.c
@@ -0,0 +1,176 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 */
18
19/****************\
20 GPIO Functions
21\****************/
22
23#include "ath5k.h"
24#include "reg.h"
25#include "debug.h"
26#include "base.h"
27
28/*
29 * Set led state
30 */
31void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
32{
33 u32 led;
34 /*5210 has different led mode handling*/
35 u32 led_5210;
36
37 ATH5K_TRACE(ah->ah_sc);
38
39 /*Reset led status*/
40 if (ah->ah_version != AR5K_AR5210)
41 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
42 AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED);
43 else
44 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
45
46 /*
47 * Some blinking values, define at your wish
48 */
49 switch (state) {
50 case AR5K_LED_SCAN:
51 case AR5K_LED_AUTH:
52 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
53 led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
54 break;
55
56 case AR5K_LED_INIT:
57 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
58 led_5210 = AR5K_PCICFG_LED_PEND;
59 break;
60
61 case AR5K_LED_ASSOC:
62 case AR5K_LED_RUN:
63 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
64 led_5210 = AR5K_PCICFG_LED_ASSOC;
65 break;
66
67 default:
68 led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
69 led_5210 = AR5K_PCICFG_LED_PEND;
70 break;
71 }
72
73 /*Write new status to the register*/
74 if (ah->ah_version != AR5K_AR5210)
75 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
76 else
77 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
78}
79
80/*
81 * Set GPIO inputs
82 */
83int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
84{
85 ATH5K_TRACE(ah->ah_sc);
86 if (gpio > AR5K_NUM_GPIO)
87 return -EINVAL;
88
89 ath5k_hw_reg_write(ah,
90 (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
91 | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
92
93 return 0;
94}
95
96/*
97 * Set GPIO outputs
98 */
99int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
100{
101 ATH5K_TRACE(ah->ah_sc);
102 if (gpio > AR5K_NUM_GPIO)
103 return -EINVAL;
104
105 ath5k_hw_reg_write(ah,
106 (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
107 | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
108
109 return 0;
110}
111
112/*
113 * Get GPIO state
114 */
115u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
116{
117 ATH5K_TRACE(ah->ah_sc);
118 if (gpio > AR5K_NUM_GPIO)
119 return 0xffffffff;
120
121 /* GPIO input magic */
122 return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
123 0x1;
124}
125
126/*
127 * Set GPIO state
128 */
129int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
130{
131 u32 data;
132 ATH5K_TRACE(ah->ah_sc);
133
134 if (gpio > AR5K_NUM_GPIO)
135 return -EINVAL;
136
137 /* GPIO output magic */
138 data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
139
140 data &= ~(1 << gpio);
141 data |= (val & 1) << gpio;
142
143 ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
144
145 return 0;
146}
147
148/*
149 * Initialize the GPIO interrupt (RFKill switch)
150 */
151void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
152 u32 interrupt_level)
153{
154 u32 data;
155
156 ATH5K_TRACE(ah->ah_sc);
157 if (gpio > AR5K_NUM_GPIO)
158 return;
159
160 /*
161 * Set the GPIO interrupt
162 */
163 data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
164 ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
165 AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
166 (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
167
168 ath5k_hw_reg_write(ah, interrupt_level ? data :
169 (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
170
171 ah->ah_imr |= AR5K_IMR_GPIO;
172
173 /* Enable GPIO interrupts */
174 AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
175}
176
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
deleted file mode 100644
index b987aa1e0f77..000000000000
--- a/drivers/net/wireless/ath5k/hw.c
+++ /dev/null
@@ -1,4492 +0,0 @@
1/*
2 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org>
5 * Copyright (c) 2007 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
6 * Copyright (c) 2007 Pavel Roskin <proski@gnu.org>
7 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 */
22
23/*
24 * HW related functions for Atheros Wireless LAN devices.
25 */
26
27#include <linux/pci.h>
28#include <linux/delay.h>
29
30#include "reg.h"
31#include "base.h"
32#include "debug.h"
33
34/* Prototypes */
35static int ath5k_hw_nic_reset(struct ath5k_hw *, u32);
36static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool);
37static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
38 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
39 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
40 unsigned int, unsigned int);
41static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
42 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
43 unsigned int);
44static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *,
45 struct ath5k_tx_status *);
46static int ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
47 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
48 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
49 unsigned int, unsigned int);
50static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *,
51 struct ath5k_tx_status *);
52static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *, struct ath5k_desc *,
53 struct ath5k_rx_status *);
54static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *, struct ath5k_desc *,
55 struct ath5k_rx_status *);
56static int ath5k_hw_get_capabilities(struct ath5k_hw *);
57
58static int ath5k_eeprom_init(struct ath5k_hw *);
59static int ath5k_eeprom_read_mac(struct ath5k_hw *, u8 *);
60
61static int ath5k_hw_enable_pspoll(struct ath5k_hw *, u8 *, u16);
62static int ath5k_hw_disable_pspoll(struct ath5k_hw *);
63
64/*
65 * Enable to overwrite the country code (use "00" for debug)
66 */
67#if 0
68#define COUNTRYCODE "00"
69#endif
70
71/*******************\
72 General Functions
73\*******************/
74
75/*
76 * Functions used internaly
77 */
78
79static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
80{
81 return turbo ? (usec * 80) : (usec * 40);
82}
83
84static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
85{
86 return turbo ? (clock / 80) : (clock / 40);
87}
88
89/*
90 * Check if a register write has been completed
91 */
92int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
93 bool is_set)
94{
95 int i;
96 u32 data;
97
98 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
99 data = ath5k_hw_reg_read(ah, reg);
100 if (is_set && (data & flag))
101 break;
102 else if ((data & flag) == val)
103 break;
104 udelay(15);
105 }
106
107 return (i <= 0) ? -EAGAIN : 0;
108}
109
110
111/***************************************\
112 Attach/Detach Functions
113\***************************************/
114
115/*
116 * Power On Self Test helper function
117 */
118static int ath5k_hw_post(struct ath5k_hw *ah)
119{
120
121 int i, c;
122 u16 cur_reg;
123 u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
124 u32 var_pattern;
125 u32 static_pattern[4] = {
126 0x55555555, 0xaaaaaaaa,
127 0x66666666, 0x99999999
128 };
129 u32 init_val;
130 u32 cur_val;
131
132 for (c = 0; c < 2; c++) {
133
134 cur_reg = regs[c];
135
136 /* Save previous value */
137 init_val = ath5k_hw_reg_read(ah, cur_reg);
138
139 for (i = 0; i < 256; i++) {
140 var_pattern = i << 16 | i;
141 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
142 cur_val = ath5k_hw_reg_read(ah, cur_reg);
143
144 if (cur_val != var_pattern) {
145 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
146 return -EAGAIN;
147 }
148
149 /* Found on ndiswrapper dumps */
150 var_pattern = 0x0039080f;
151 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
152 }
153
154 for (i = 0; i < 4; i++) {
155 var_pattern = static_pattern[i];
156 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
157 cur_val = ath5k_hw_reg_read(ah, cur_reg);
158
159 if (cur_val != var_pattern) {
160 ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
161 return -EAGAIN;
162 }
163
164 /* Found on ndiswrapper dumps */
165 var_pattern = 0x003b080f;
166 ath5k_hw_reg_write(ah, var_pattern, cur_reg);
167 }
168
169 /* Restore previous value */
170 ath5k_hw_reg_write(ah, init_val, cur_reg);
171
172 }
173
174 return 0;
175
176}
177
178/*
179 * Check if the device is supported and initialize the needed structs
180 */
181struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
182{
183 struct ath5k_hw *ah;
184 struct pci_dev *pdev = sc->pdev;
185 u8 mac[ETH_ALEN];
186 int ret;
187 u32 srev;
188
189 /*If we passed the test malloc a ath5k_hw struct*/
190 ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
191 if (ah == NULL) {
192 ret = -ENOMEM;
193 ATH5K_ERR(sc, "out of memory\n");
194 goto err;
195 }
196
197 ah->ah_sc = sc;
198 ah->ah_iobase = sc->iobase;
199
200 /*
201 * HW information
202 */
203
204 ah->ah_op_mode = IEEE80211_IF_TYPE_STA;
205 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
206 ah->ah_turbo = false;
207 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
208 ah->ah_imr = 0;
209 ah->ah_atim_window = 0;
210 ah->ah_aifs = AR5K_TUNE_AIFS;
211 ah->ah_cw_min = AR5K_TUNE_CWMIN;
212 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
213 ah->ah_software_retry = false;
214 ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
215
216 /*
217 * Set the mac revision based on the pci id
218 */
219 ah->ah_version = mac_version;
220
221 /*Fill the ath5k_hw struct with the needed functions*/
222 if (ah->ah_version == AR5K_AR5212)
223 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
224 else if (ah->ah_version == AR5K_AR5211)
225 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
226
227 if (ah->ah_version == AR5K_AR5212) {
228 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
229 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
230 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
231 } else {
232 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
233 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
234 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
235 }
236
237 if (ah->ah_version == AR5K_AR5212)
238 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
239 else if (ah->ah_version <= AR5K_AR5211)
240 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
241
242 /* Bring device out of sleep and reset it's units */
243 ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true);
244 if (ret)
245 goto err_free;
246
247 /* Get MAC, PHY and RADIO revisions */
248 srev = ath5k_hw_reg_read(ah, AR5K_SREV);
249 ah->ah_mac_srev = srev;
250 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
251 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
252 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
253 0xffffffff;
254 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
255 CHANNEL_5GHZ);
256
257 if (ah->ah_version == AR5K_AR5210)
258 ah->ah_radio_2ghz_revision = 0;
259 else
260 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
261 CHANNEL_2GHZ);
262
263 /* Return on unsuported chips (unsupported eeprom etc) */
264 if ((srev >= AR5K_SREV_VER_AR5416) &&
265 (srev < AR5K_SREV_VER_AR2425)) {
266 ATH5K_ERR(sc, "Device not yet supported.\n");
267 ret = -ENODEV;
268 goto err_free;
269 } else if (srev == AR5K_SREV_VER_AR2425) {
270 ATH5K_WARN(sc, "Support for RF2425 is under development.\n");
271 }
272
273 /* Identify single chip solutions */
274 if (((srev <= AR5K_SREV_VER_AR5414) &&
275 (srev >= AR5K_SREV_VER_AR2413)) ||
276 (srev == AR5K_SREV_VER_AR2425)) {
277 ah->ah_single_chip = true;
278 } else {
279 ah->ah_single_chip = false;
280 }
281
282 /* Single chip radio */
283 if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
284 ah->ah_radio_2ghz_revision = 0;
285
286 /* Identify the radio chip*/
287 if (ah->ah_version == AR5K_AR5210) {
288 ah->ah_radio = AR5K_RF5110;
289 /*
290 * Register returns 0x0/0x04 for radio revision
291 * so ath5k_hw_radio_revision doesn't parse the value
292 * correctly. For now we are based on mac's srev to
293 * identify RF2425 radio.
294 */
295 } else if (srev == AR5K_SREV_VER_AR2425) {
296 ah->ah_radio = AR5K_RF2425;
297 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
298 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
299 ah->ah_radio = AR5K_RF5111;
300 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
301 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
302 ah->ah_radio = AR5K_RF5112;
303 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
304 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
305 ah->ah_radio = AR5K_RF2413;
306 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
307 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
308 ah->ah_radio = AR5K_RF5413;
309 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
310 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
311 /* AR5424 */
312 if (srev >= AR5K_SREV_VER_AR5424) {
313 ah->ah_radio = AR5K_RF5413;
314 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
315 /* AR2424 */
316 } else {
317 ah->ah_radio = AR5K_RF2413; /* For testing */
318 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
319 }
320 }
321 ah->ah_phy = AR5K_PHY(0);
322
323 /*
324 * Write PCI-E power save settings
325 */
326 if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
327 ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
328 ath5k_hw_reg_write(ah, 0x24924924, 0x4080);
329 ath5k_hw_reg_write(ah, 0x28000039, 0x4080);
330 ath5k_hw_reg_write(ah, 0x53160824, 0x4080);
331 ath5k_hw_reg_write(ah, 0xe5980579, 0x4080);
332 ath5k_hw_reg_write(ah, 0x001defff, 0x4080);
333 ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080);
334 ath5k_hw_reg_write(ah, 0xbe105554, 0x4080);
335 ath5k_hw_reg_write(ah, 0x000e3007, 0x4080);
336 ath5k_hw_reg_write(ah, 0x00000000, 0x4084);
337 }
338
339 /*
340 * POST
341 */
342 ret = ath5k_hw_post(ah);
343 if (ret)
344 goto err_free;
345
346 /* Write AR5K_PCICFG_UNK on 2112B and later chips */
347 if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B ||
348 srev > AR5K_SREV_VER_AR2413) {
349 ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG);
350 }
351
352 /*
353 * Get card capabilities, values, ...
354 */
355 ret = ath5k_eeprom_init(ah);
356 if (ret) {
357 ATH5K_ERR(sc, "unable to init EEPROM\n");
358 goto err_free;
359 }
360
361 /* Get misc capabilities */
362 ret = ath5k_hw_get_capabilities(ah);
363 if (ret) {
364 ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
365 sc->pdev->device);
366 goto err_free;
367 }
368
369 /* Get MAC address */
370 ret = ath5k_eeprom_read_mac(ah, mac);
371 if (ret) {
372 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
373 sc->pdev->device);
374 goto err_free;
375 }
376
377 ath5k_hw_set_lladdr(ah, mac);
378 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
379 memset(ah->ah_bssid, 0xff, ETH_ALEN);
380 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
381 ath5k_hw_set_opmode(ah);
382
383 ath5k_hw_set_rfgain_opt(ah);
384
385 return ah;
386err_free:
387 kfree(ah);
388err:
389 return ERR_PTR(ret);
390}
391
392/*
393 * Bring up MAC + PHY Chips
394 */
395static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
396{
397 struct pci_dev *pdev = ah->ah_sc->pdev;
398 u32 turbo, mode, clock, bus_flags;
399 int ret;
400
401 turbo = 0;
402 mode = 0;
403 clock = 0;
404
405 ATH5K_TRACE(ah->ah_sc);
406
407 /* Wakeup the device */
408 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
409 if (ret) {
410 ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
411 return ret;
412 }
413
414 if (ah->ah_version != AR5K_AR5210) {
415 /*
416 * Get channel mode flags
417 */
418
419 if (ah->ah_radio >= AR5K_RF5112) {
420 mode = AR5K_PHY_MODE_RAD_RF5112;
421 clock = AR5K_PHY_PLL_RF5112;
422 } else {
423 mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/
424 clock = AR5K_PHY_PLL_RF5111; /*Zero*/
425 }
426
427 if (flags & CHANNEL_2GHZ) {
428 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
429 clock |= AR5K_PHY_PLL_44MHZ;
430
431 if (flags & CHANNEL_CCK) {
432 mode |= AR5K_PHY_MODE_MOD_CCK;
433 } else if (flags & CHANNEL_OFDM) {
434 /* XXX Dynamic OFDM/CCK is not supported by the
435 * AR5211 so we set MOD_OFDM for plain g (no
436 * CCK headers) operation. We need to test
437 * this, 5211 might support ofdm-only g after
438 * all, there are also initial register values
439 * in the code for g mode (see initvals.c). */
440 if (ah->ah_version == AR5K_AR5211)
441 mode |= AR5K_PHY_MODE_MOD_OFDM;
442 else
443 mode |= AR5K_PHY_MODE_MOD_DYN;
444 } else {
445 ATH5K_ERR(ah->ah_sc,
446 "invalid radio modulation mode\n");
447 return -EINVAL;
448 }
449 } else if (flags & CHANNEL_5GHZ) {
450 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
451 clock |= AR5K_PHY_PLL_40MHZ;
452
453 if (flags & CHANNEL_OFDM)
454 mode |= AR5K_PHY_MODE_MOD_OFDM;
455 else {
456 ATH5K_ERR(ah->ah_sc,
457 "invalid radio modulation mode\n");
458 return -EINVAL;
459 }
460 } else {
461 ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
462 return -EINVAL;
463 }
464
465 if (flags & CHANNEL_TURBO)
466 turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
467 } else { /* Reset the device */
468
469 /* ...enable Atheros turbo mode if requested */
470 if (flags & CHANNEL_TURBO)
471 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
472 AR5K_PHY_TURBO);
473 }
474
475 /* reseting PCI on PCI-E cards results card to hang
476 * and always return 0xffff... so we ingore that flag
477 * for PCI-E cards */
478 bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
479
480 /* Reset chipset */
481 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
482 AR5K_RESET_CTL_BASEBAND | bus_flags);
483 if (ret) {
484 ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
485 return -EIO;
486 }
487
488 if (ah->ah_version == AR5K_AR5210)
489 udelay(2300);
490
491 /* ...wakeup again!*/
492 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
493 if (ret) {
494 ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
495 return ret;
496 }
497
498 /* ...final warm reset */
499 if (ath5k_hw_nic_reset(ah, 0)) {
500 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
501 return -EIO;
502 }
503
504 if (ah->ah_version != AR5K_AR5210) {
505 /* ...set the PHY operating mode */
506 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
507 udelay(300);
508
509 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
510 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
511 }
512
513 return 0;
514}
515
516/*
517 * Free the ath5k_hw struct
518 */
519void ath5k_hw_detach(struct ath5k_hw *ah)
520{
521 ATH5K_TRACE(ah->ah_sc);
522
523 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
524
525 if (ah->ah_rf_banks != NULL)
526 kfree(ah->ah_rf_banks);
527
528 /* assume interrupts are down */
529 kfree(ah);
530}
531
532/****************************\
533 Reset function and helpers
534\****************************/
535
536/**
537 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
538 *
539 * @ah: the &struct ath5k_hw
540 * @channel: the currently set channel upon reset
541 *
542 * Write the OFDM timings for the AR5212 upon reset. This is a helper for
543 * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
544 * depending on the bandwidth of the channel.
545 *
546 */
547static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
548 struct ieee80211_channel *channel)
549{
550 /* Get exponent and mantissa and set it */
551 u32 coef_scaled, coef_exp, coef_man,
552 ds_coef_exp, ds_coef_man, clock;
553
554 if (!(ah->ah_version == AR5K_AR5212) ||
555 !(channel->hw_value & CHANNEL_OFDM))
556 BUG();
557
558 /* Seems there are two PLLs, one for baseband sampling and one
559 * for tuning. Tuning basebands are 40 MHz or 80MHz when in
560 * turbo. */
561 clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
562 coef_scaled = ((5 * (clock << 24)) / 2) /
563 channel->center_freq;
564
565 for (coef_exp = 31; coef_exp > 0; coef_exp--)
566 if ((coef_scaled >> coef_exp) & 0x1)
567 break;
568
569 if (!coef_exp)
570 return -EINVAL;
571
572 coef_exp = 14 - (coef_exp - 24);
573 coef_man = coef_scaled +
574 (1 << (24 - coef_exp - 1));
575 ds_coef_man = coef_man >> (24 - coef_exp);
576 ds_coef_exp = coef_exp - 16;
577
578 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
579 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
580 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
581 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
582
583 return 0;
584}
585
586
587/*
588 * index into rates for control rates, we can set it up like this because
589 * this is only used for AR5212 and we know it supports G mode
590 */
591static int control_rates[] =
592 { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
593
594/**
595 * ath5k_hw_write_rate_duration - set rate duration during hw resets
596 *
597 * @ah: the &struct ath5k_hw
598 * @mode: one of enum ath5k_driver_mode
599 *
600 * Write the rate duration table upon hw reset. This is a helper for
601 * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for
602 * the hardware for the current mode for each rate. The rates which are capable
603 * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another
604 * register for the short preamble ACK timeout calculation.
605 */
606static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
607 unsigned int mode)
608{
609 struct ath5k_softc *sc = ah->ah_sc;
610 struct ieee80211_rate *rate;
611 unsigned int i;
612
613 /* Write rate duration table */
614 for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
615 u32 reg;
616 u16 tx_time;
617
618 rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
619
620 /* Set ACK timeout */
621 reg = AR5K_RATE_DUR(rate->hw_value);
622
623 /* An ACK frame consists of 10 bytes. If you add the FCS,
624 * which ieee80211_generic_frame_duration() adds,
625 * its 14 bytes. Note we use the control rate and not the
626 * actual rate for this rate. See mac80211 tx.c
627 * ieee80211_duration() for a brief description of
628 * what rate we should choose to TX ACKs. */
629 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
630 sc->vif, 10, rate));
631
632 ath5k_hw_reg_write(ah, tx_time, reg);
633
634 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
635 continue;
636
637 /*
638 * We're not distinguishing short preamble here,
639 * This is true, all we'll get is a longer value here
640 * which is not necessarilly bad. We could use
641 * export ieee80211_frame_duration() but that needs to be
642 * fixed first to be properly used by mac802111 drivers:
643 *
644 * - remove erp stuff and let the routine figure ofdm
645 * erp rates
646 * - remove passing argument ieee80211_local as
647 * drivers don't have access to it
648 * - move drivers using ieee80211_generic_frame_duration()
649 * to this
650 */
651 ath5k_hw_reg_write(ah, tx_time,
652 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
653 }
654}
655
656/*
657 * Main reset function
658 */
659int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
660 struct ieee80211_channel *channel, bool change_channel)
661{
662 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
663 struct pci_dev *pdev = ah->ah_sc->pdev;
664 u32 data, s_seq, s_ant, s_led[3], dma_size;
665 unsigned int i, mode, freq, ee_mode, ant[2];
666 int ret;
667
668 ATH5K_TRACE(ah->ah_sc);
669
670 s_seq = 0;
671 s_ant = 0;
672 ee_mode = 0;
673 freq = 0;
674 mode = 0;
675
676 /*
677 * Save some registers before a reset
678 */
679 /*DCU/Antenna selection not available on 5210*/
680 if (ah->ah_version != AR5K_AR5210) {
681 if (change_channel) {
682 /* Seq number for queue 0 -do this for all queues ? */
683 s_seq = ath5k_hw_reg_read(ah,
684 AR5K_QUEUE_DFS_SEQNUM(0));
685 /*Default antenna*/
686 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
687 }
688 }
689
690 /*GPIOs*/
691 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
692 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
693 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
694
695 if (change_channel && ah->ah_rf_banks != NULL)
696 ath5k_hw_get_rf_gain(ah);
697
698
699 /*Wakeup the device*/
700 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
701 if (ret)
702 return ret;
703
704 /*
705 * Initialize operating mode
706 */
707 ah->ah_op_mode = op_mode;
708
709 /*
710 * 5111/5112 Settings
711 * 5210 only comes with RF5110
712 */
713 if (ah->ah_version != AR5K_AR5210) {
714 if (ah->ah_radio != AR5K_RF5111 &&
715 ah->ah_radio != AR5K_RF5112 &&
716 ah->ah_radio != AR5K_RF5413 &&
717 ah->ah_radio != AR5K_RF2413 &&
718 ah->ah_radio != AR5K_RF2425) {
719 ATH5K_ERR(ah->ah_sc,
720 "invalid phy radio: %u\n", ah->ah_radio);
721 return -EINVAL;
722 }
723
724 switch (channel->hw_value & CHANNEL_MODES) {
725 case CHANNEL_A:
726 mode = AR5K_MODE_11A;
727 freq = AR5K_INI_RFGAIN_5GHZ;
728 ee_mode = AR5K_EEPROM_MODE_11A;
729 break;
730 case CHANNEL_G:
731 mode = AR5K_MODE_11G;
732 freq = AR5K_INI_RFGAIN_2GHZ;
733 ee_mode = AR5K_EEPROM_MODE_11G;
734 break;
735 case CHANNEL_B:
736 mode = AR5K_MODE_11B;
737 freq = AR5K_INI_RFGAIN_2GHZ;
738 ee_mode = AR5K_EEPROM_MODE_11B;
739 break;
740 case CHANNEL_T:
741 mode = AR5K_MODE_11A_TURBO;
742 freq = AR5K_INI_RFGAIN_5GHZ;
743 ee_mode = AR5K_EEPROM_MODE_11A;
744 break;
745 /*Is this ok on 5211 too ?*/
746 case CHANNEL_TG:
747 mode = AR5K_MODE_11G_TURBO;
748 freq = AR5K_INI_RFGAIN_2GHZ;
749 ee_mode = AR5K_EEPROM_MODE_11G;
750 break;
751 case CHANNEL_XR:
752 if (ah->ah_version == AR5K_AR5211) {
753 ATH5K_ERR(ah->ah_sc,
754 "XR mode not available on 5211");
755 return -EINVAL;
756 }
757 mode = AR5K_MODE_XR;
758 freq = AR5K_INI_RFGAIN_5GHZ;
759 ee_mode = AR5K_EEPROM_MODE_11A;
760 break;
761 default:
762 ATH5K_ERR(ah->ah_sc,
763 "invalid channel: %d\n", channel->center_freq);
764 return -EINVAL;
765 }
766
767 /* PHY access enable */
768 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
769
770 }
771
772 ret = ath5k_hw_write_initvals(ah, mode, change_channel);
773 if (ret)
774 return ret;
775
776 /*
777 * 5211/5212 Specific
778 */
779 if (ah->ah_version != AR5K_AR5210) {
780 /*
781 * Write initial RF gain settings
782 * This should work for both 5111/5112
783 */
784 ret = ath5k_hw_rfgain(ah, freq);
785 if (ret)
786 return ret;
787
788 mdelay(1);
789
790 /*
791 * Write some more initial register settings
792 */
793 if (ah->ah_version == AR5K_AR5212) {
794 ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
795
796 if (channel->hw_value == CHANNEL_G)
797 if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
798 ath5k_hw_reg_write(ah, 0x00f80d80,
799 0x994c);
800 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
801 ath5k_hw_reg_write(ah, 0x00380140,
802 0x994c);
803 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
804 ath5k_hw_reg_write(ah, 0x00fc0ec0,
805 0x994c);
806 else /* 2425 */
807 ath5k_hw_reg_write(ah, 0x00fc0fc0,
808 0x994c);
809 else
810 ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
811
812 /* Some bits are disabled here, we know nothing about
813 * register 0xa228 yet, most of the times this ends up
814 * with a value 0x9b5 -haven't seen any dump with
815 * a different value- */
816 /* Got this from decompiling binary HAL */
817 data = ath5k_hw_reg_read(ah, 0xa228);
818 data &= 0xfffffdff;
819 ath5k_hw_reg_write(ah, data, 0xa228);
820
821 data = ath5k_hw_reg_read(ah, 0xa228);
822 data &= 0xfffe03ff;
823 ath5k_hw_reg_write(ah, data, 0xa228);
824 data = 0;
825
826 /* Just write 0x9b5 ? */
827 /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
828 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
829 ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
830 ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
831 }
832
833 /* Fix for first revision of the RF5112 RF chipset */
834 if (ah->ah_radio >= AR5K_RF5112 &&
835 ah->ah_radio_5ghz_revision <
836 AR5K_SREV_RAD_5112A) {
837 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
838 AR5K_PHY_CCKTXCTL);
839 if (channel->hw_value & CHANNEL_5GHZ)
840 data = 0xffb81020;
841 else
842 data = 0xffb80d20;
843 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
844 data = 0;
845 }
846
847 /*
848 * Set TX power (FIXME)
849 */
850 ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
851 if (ret)
852 return ret;
853
854 /* Write rate duration table only on AR5212 and if
855 * virtual interface has already been brought up
856 * XXX: rethink this after new mode changes to
857 * mac80211 are integrated */
858 if (ah->ah_version == AR5K_AR5212 &&
859 ah->ah_sc->vif != NULL)
860 ath5k_hw_write_rate_duration(ah, mode);
861
862 /*
863 * Write RF registers
864 */
865 ret = ath5k_hw_rfregs(ah, channel, mode);
866 if (ret)
867 return ret;
868
869 /*
870 * Configure additional registers
871 */
872
873 /* Write OFDM timings on 5212*/
874 if (ah->ah_version == AR5K_AR5212 &&
875 channel->hw_value & CHANNEL_OFDM) {
876 ret = ath5k_hw_write_ofdm_timings(ah, channel);
877 if (ret)
878 return ret;
879 }
880
881 /*Enable/disable 802.11b mode on 5111
882 (enable 2111 frequency converter + CCK)*/
883 if (ah->ah_radio == AR5K_RF5111) {
884 if (mode == AR5K_MODE_11B)
885 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
886 AR5K_TXCFG_B_MODE);
887 else
888 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
889 AR5K_TXCFG_B_MODE);
890 }
891
892 /*
893 * Set channel and calibrate the PHY
894 */
895 ret = ath5k_hw_channel(ah, channel);
896 if (ret)
897 return ret;
898
899 /* Set antenna mode */
900 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
901 ah->ah_antenna[ee_mode][0], 0xfffffc06);
902
903 /*
904 * In case a fixed antenna was set as default
905 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
906 * registers.
907 */
908 if (s_ant != 0){
909 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
910 ant[0] = ant[1] = AR5K_ANT_FIXED_A;
911 else /* 2 - Aux */
912 ant[0] = ant[1] = AR5K_ANT_FIXED_B;
913 } else {
914 ant[0] = AR5K_ANT_FIXED_A;
915 ant[1] = AR5K_ANT_FIXED_B;
916 }
917
918 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
919 AR5K_PHY_ANT_SWITCH_TABLE_0);
920 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
921 AR5K_PHY_ANT_SWITCH_TABLE_1);
922
923 /* Commit values from EEPROM */
924 if (ah->ah_radio == AR5K_RF5111)
925 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
926 AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
927
928 ath5k_hw_reg_write(ah,
929 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
930 AR5K_PHY_NFTHRES);
931
932 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
933 (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
934 0xffffc07f);
935 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
936 (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
937 0xfffc0fff);
938 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
939 (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
940 ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
941 0xffff0000);
942
943 ath5k_hw_reg_write(ah,
944 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
945 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
946 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
947 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
948
949 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
950 ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
951 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
952 (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
953 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
954
955 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
956 AR5K_PHY_IQ_CORR_ENABLE |
957 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
958 ee->ee_q_cal[ee_mode]);
959
960 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
961 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
962 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
963 ee->ee_margin_tx_rx[ee_mode]);
964
965 } else {
966 mdelay(1);
967 /* Disable phy and wait */
968 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
969 mdelay(1);
970 }
971
972 /*
973 * Restore saved values
974 */
975 /*DCU/Antenna selection not available on 5210*/
976 if (ah->ah_version != AR5K_AR5210) {
977 ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
978 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
979 }
980 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
981 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
982 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
983
984 /*
985 * Misc
986 */
987 /* XXX: add ah->aid once mac80211 gives this to us */
988 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
989
990 ath5k_hw_set_opmode(ah);
991 /*PISR/SISR Not available on 5210*/
992 if (ah->ah_version != AR5K_AR5210) {
993 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
994 /* If we later allow tuning for this, store into sc structure */
995 data = AR5K_TUNE_RSSI_THRES |
996 AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
997 ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
998 }
999
1000 /*
1001 * Set Rx/Tx DMA Configuration
1002 *
1003 * Set maximum DMA size (512) except for PCI-E cards since
1004 * it causes rx overruns and tx errors (tested on 5424 but since
1005 * rx overruns also occur on 5416/5418 with madwifi we set 128
1006 * for all PCI-E cards to be safe).
1007 *
1008 * In dumps this is 128 for allchips.
1009 *
1010 * XXX: need to check 5210 for this
1011 * TODO: Check out tx triger level, it's always 64 on dumps but I
1012 * guess we can tweak it and see how it goes ;-)
1013 */
1014 dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
1015 if (ah->ah_version != AR5K_AR5210) {
1016 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1017 AR5K_TXCFG_SDMAMR, dma_size);
1018 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
1019 AR5K_RXCFG_SDMAMW, dma_size);
1020 }
1021
1022 /*
1023 * Enable the PHY and wait until completion
1024 */
1025 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
1026
1027 /*
1028 * On 5211+ read activation -> rx delay
1029 * and use it.
1030 */
1031 if (ah->ah_version != AR5K_AR5210) {
1032 data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
1033 AR5K_PHY_RX_DELAY_M;
1034 data = (channel->hw_value & CHANNEL_CCK) ?
1035 ((data << 2) / 22) : (data / 10);
1036
1037 udelay(100 + (2 * data));
1038 data = 0;
1039 } else {
1040 mdelay(1);
1041 }
1042
1043 /*
1044 * Perform ADC test (?)
1045 */
1046 data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
1047 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
1048 for (i = 0; i <= 20; i++) {
1049 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
1050 break;
1051 udelay(200);
1052 }
1053 ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
1054 data = 0;
1055
1056 /*
1057 * Start automatic gain calibration
1058 *
1059 * During AGC calibration RX path is re-routed to
1060 * a signal detector so we don't receive anything.
1061 *
1062 * This method is used to calibrate some static offsets
1063 * used together with on-the fly I/Q calibration (the
1064 * one performed via ath5k_hw_phy_calibrate), that doesn't
1065 * interrupt rx path.
1066 *
1067 * If we are in a noisy environment AGC calibration may time
1068 * out.
1069 */
1070 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1071 AR5K_PHY_AGCCTL_CAL);
1072
1073 /* At the same time start I/Q calibration for QAM constellation
1074 * -no need for CCK- */
1075 ah->ah_calibration = false;
1076 if (!(mode == AR5K_MODE_11B)) {
1077 ah->ah_calibration = true;
1078 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
1079 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
1080 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
1081 AR5K_PHY_IQ_RUN);
1082 }
1083
1084 /* Wait for gain calibration to finish (we check for I/Q calibration
1085 * during ath5k_phy_calibrate) */
1086 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1087 AR5K_PHY_AGCCTL_CAL, 0, false)) {
1088 ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
1089 channel->center_freq);
1090 return -EAGAIN;
1091 }
1092
1093 /*
1094 * Start noise floor calibration
1095 *
1096 * If we run NF calibration before AGC, it always times out.
1097 * Binary HAL starts NF and AGC calibration at the same time
1098 * and only waits for AGC to finish. I believe that's wrong because
1099 * during NF calibration, rx path is also routed to a detector, so if
1100 * it doesn't finish we won't have RX.
1101 *
1102 * XXX: Find an interval that's OK for all cards...
1103 */
1104 ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
1105 if (ret)
1106 return ret;
1107
1108 /*
1109 * Reset queues and start beacon timers at the end of the reset routine
1110 */
1111 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
1112 /*No QCU on 5210*/
1113 if (ah->ah_version != AR5K_AR5210)
1114 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
1115
1116 ret = ath5k_hw_reset_tx_queue(ah, i);
1117 if (ret) {
1118 ATH5K_ERR(ah->ah_sc,
1119 "failed to reset TX queue #%d\n", i);
1120 return ret;
1121 }
1122 }
1123
1124 /* Pre-enable interrupts on 5211/5212*/
1125 if (ah->ah_version != AR5K_AR5210)
1126 ath5k_hw_set_intr(ah, AR5K_INT_RX | AR5K_INT_TX |
1127 AR5K_INT_FATAL);
1128
1129 /*
1130 * Set RF kill flags if supported by the device (read from the EEPROM)
1131 * Disable gpio_intr for now since it results system hang.
1132 * TODO: Handle this in ath5k_intr
1133 */
1134#if 0
1135 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
1136 ath5k_hw_set_gpio_input(ah, 0);
1137 ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
1138 if (ah->ah_gpio[0] == 0)
1139 ath5k_hw_set_gpio_intr(ah, 0, 1);
1140 else
1141 ath5k_hw_set_gpio_intr(ah, 0, 0);
1142 }
1143#endif
1144
1145 /*
1146 * Set the 32MHz reference clock on 5212 phy clock sleep register
1147 *
1148 * TODO: Find out how to switch to external 32Khz clock to save power
1149 */
1150 if (ah->ah_version == AR5K_AR5212) {
1151 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
1152 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
1153 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
1154 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
1155 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
1156 ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
1157
1158 data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
1159 data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
1160 0x00000f80 : 0x00001380 ;
1161 ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
1162 data = 0;
1163 }
1164
1165 if (ah->ah_version == AR5K_AR5212) {
1166 ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
1167 ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
1168 ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
1169 if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
1170 ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
1171 }
1172
1173 /*
1174 * Disable beacons and reset the register
1175 */
1176 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
1177 AR5K_BEACON_RESET_TSF);
1178
1179 return 0;
1180}
1181
1182/*
1183 * Reset chipset
1184 */
1185static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
1186{
1187 int ret;
1188 u32 mask = val ? val : ~0U;
1189
1190 ATH5K_TRACE(ah->ah_sc);
1191
1192 /* Read-and-clear RX Descriptor Pointer*/
1193 ath5k_hw_reg_read(ah, AR5K_RXDP);
1194
1195 /*
1196 * Reset the device and wait until success
1197 */
1198 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
1199
1200 /* Wait at least 128 PCI clocks */
1201 udelay(15);
1202
1203 if (ah->ah_version == AR5K_AR5210) {
1204 val &= AR5K_RESET_CTL_CHIP;
1205 mask &= AR5K_RESET_CTL_CHIP;
1206 } else {
1207 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1208 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1209 }
1210
1211 ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
1212
1213 /*
1214 * Reset configuration register (for hw byte-swap). Note that this
1215 * is only set for big endian. We do the necessary magic in
1216 * AR5K_INIT_CFG.
1217 */
1218 if ((val & AR5K_RESET_CTL_PCU) == 0)
1219 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
1220
1221 return ret;
1222}
1223
1224/*
1225 * Power management functions
1226 */
1227
1228/*
1229 * Sleep control
1230 */
1231int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
1232 bool set_chip, u16 sleep_duration)
1233{
1234 unsigned int i;
1235 u32 staid, data;
1236
1237 ATH5K_TRACE(ah->ah_sc);
1238 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
1239
1240 switch (mode) {
1241 case AR5K_PM_AUTO:
1242 staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
1243 /* fallthrough */
1244 case AR5K_PM_NETWORK_SLEEP:
1245 if (set_chip)
1246 ath5k_hw_reg_write(ah,
1247 AR5K_SLEEP_CTL_SLE_ALLOW |
1248 sleep_duration,
1249 AR5K_SLEEP_CTL);
1250
1251 staid |= AR5K_STA_ID1_PWR_SV;
1252 break;
1253
1254 case AR5K_PM_FULL_SLEEP:
1255 if (set_chip)
1256 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
1257 AR5K_SLEEP_CTL);
1258
1259 staid |= AR5K_STA_ID1_PWR_SV;
1260 break;
1261
1262 case AR5K_PM_AWAKE:
1263
1264 staid &= ~AR5K_STA_ID1_PWR_SV;
1265
1266 if (!set_chip)
1267 goto commit;
1268
1269 /* Preserve sleep duration */
1270 data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
1271 if( data & 0xffc00000 ){
1272 data = 0;
1273 } else {
1274 data = data & 0xfffcffff;
1275 }
1276
1277 ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
1278 udelay(15);
1279
1280 for (i = 50; i > 0; i--) {
1281 /* Check if the chip did wake up */
1282 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
1283 AR5K_PCICFG_SPWR_DN) == 0)
1284 break;
1285
1286 /* Wait a bit and retry */
1287 udelay(200);
1288 ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
1289 }
1290
1291 /* Fail if the chip didn't wake up */
1292 if (i <= 0)
1293 return -EIO;
1294
1295 break;
1296
1297 default:
1298 return -EINVAL;
1299 }
1300
1301commit:
1302 ah->ah_power_mode = mode;
1303 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
1304
1305 return 0;
1306}
1307
1308/***********************\
1309 DMA Related Functions
1310\***********************/
1311
1312/*
1313 * Receive functions
1314 */
1315
1316/*
1317 * Start DMA receive
1318 */
1319void ath5k_hw_start_rx(struct ath5k_hw *ah)
1320{
1321 ATH5K_TRACE(ah->ah_sc);
1322 ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
1323 ath5k_hw_reg_read(ah, AR5K_CR);
1324}
1325
1326/*
1327 * Stop DMA receive
1328 */
1329int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
1330{
1331 unsigned int i;
1332
1333 ATH5K_TRACE(ah->ah_sc);
1334 ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
1335
1336 /*
1337 * It may take some time to disable the DMA receive unit
1338 */
1339 for (i = 2000; i > 0 &&
1340 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
1341 i--)
1342 udelay(10);
1343
1344 return i ? 0 : -EBUSY;
1345}
1346
1347/*
1348 * Get the address of the RX Descriptor
1349 */
1350u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah)
1351{
1352 return ath5k_hw_reg_read(ah, AR5K_RXDP);
1353}
1354
1355/*
1356 * Set the address of the RX Descriptor
1357 */
1358void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr)
1359{
1360 ATH5K_TRACE(ah->ah_sc);
1361
1362 /*TODO:Shouldn't we check if RX is enabled first ?*/
1363 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
1364}
1365
1366/*
1367 * Transmit functions
1368 */
1369
1370/*
1371 * Start DMA transmit for a specific queue
1372 * (see also QCU/DCU functions)
1373 */
1374int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue)
1375{
1376 u32 tx_queue;
1377
1378 ATH5K_TRACE(ah->ah_sc);
1379 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1380
1381 /* Return if queue is declared inactive */
1382 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1383 return -EIO;
1384
1385 if (ah->ah_version == AR5K_AR5210) {
1386 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1387
1388 /*
1389 * Set the queue by type on 5210
1390 */
1391 switch (ah->ah_txq[queue].tqi_type) {
1392 case AR5K_TX_QUEUE_DATA:
1393 tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
1394 break;
1395 case AR5K_TX_QUEUE_BEACON:
1396 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1397 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
1398 AR5K_BSR);
1399 break;
1400 case AR5K_TX_QUEUE_CAB:
1401 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1402 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
1403 AR5K_BCR_BDMAE, AR5K_BSR);
1404 break;
1405 default:
1406 return -EINVAL;
1407 }
1408 /* Start queue */
1409 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
1410 ath5k_hw_reg_read(ah, AR5K_CR);
1411 } else {
1412 /* Return if queue is disabled */
1413 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
1414 return -EIO;
1415
1416 /* Start queue */
1417 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
1418 }
1419
1420 return 0;
1421}
1422
1423/*
1424 * Stop DMA transmit for a specific queue
1425 * (see also QCU/DCU functions)
1426 */
1427int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
1428{
1429 unsigned int i = 100;
1430 u32 tx_queue, pending;
1431
1432 ATH5K_TRACE(ah->ah_sc);
1433 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1434
1435 /* Return if queue is declared inactive */
1436 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1437 return -EIO;
1438
1439 if (ah->ah_version == AR5K_AR5210) {
1440 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1441
1442 /*
1443 * Set by queue type
1444 */
1445 switch (ah->ah_txq[queue].tqi_type) {
1446 case AR5K_TX_QUEUE_DATA:
1447 tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
1448 break;
1449 case AR5K_TX_QUEUE_BEACON:
1450 case AR5K_TX_QUEUE_CAB:
1451 /* XXX Fix me... */
1452 tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
1453 ath5k_hw_reg_write(ah, 0, AR5K_BSR);
1454 break;
1455 default:
1456 return -EINVAL;
1457 }
1458
1459 /* Stop queue */
1460 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
1461 ath5k_hw_reg_read(ah, AR5K_CR);
1462 } else {
1463 /*
1464 * Schedule TX disable and wait until queue is empty
1465 */
1466 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
1467
1468 /*Check for pending frames*/
1469 do {
1470 pending = ath5k_hw_reg_read(ah,
1471 AR5K_QUEUE_STATUS(queue)) &
1472 AR5K_QCU_STS_FRMPENDCNT;
1473 udelay(100);
1474 } while (--i && pending);
1475
1476 /* Clear register */
1477 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
1478 if (pending)
1479 return -EBUSY;
1480 }
1481
1482 /* TODO: Check for success else return error */
1483 return 0;
1484}
1485
1486/*
1487 * Get the address of the TX Descriptor for a specific queue
1488 * (see also QCU/DCU functions)
1489 */
1490u32 ath5k_hw_get_tx_buf(struct ath5k_hw *ah, unsigned int queue)
1491{
1492 u16 tx_reg;
1493
1494 ATH5K_TRACE(ah->ah_sc);
1495 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1496
1497 /*
1498 * Get the transmit queue descriptor pointer from the selected queue
1499 */
1500 /*5210 doesn't have QCU*/
1501 if (ah->ah_version == AR5K_AR5210) {
1502 switch (ah->ah_txq[queue].tqi_type) {
1503 case AR5K_TX_QUEUE_DATA:
1504 tx_reg = AR5K_NOQCU_TXDP0;
1505 break;
1506 case AR5K_TX_QUEUE_BEACON:
1507 case AR5K_TX_QUEUE_CAB:
1508 tx_reg = AR5K_NOQCU_TXDP1;
1509 break;
1510 default:
1511 return 0xffffffff;
1512 }
1513 } else {
1514 tx_reg = AR5K_QUEUE_TXDP(queue);
1515 }
1516
1517 return ath5k_hw_reg_read(ah, tx_reg);
1518}
1519
1520/*
1521 * Set the address of the TX Descriptor for a specific queue
1522 * (see also QCU/DCU functions)
1523 */
1524int ath5k_hw_put_tx_buf(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
1525{
1526 u16 tx_reg;
1527
1528 ATH5K_TRACE(ah->ah_sc);
1529 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1530
1531 /*
1532 * Set the transmit queue descriptor pointer register by type
1533 * on 5210
1534 */
1535 if (ah->ah_version == AR5K_AR5210) {
1536 switch (ah->ah_txq[queue].tqi_type) {
1537 case AR5K_TX_QUEUE_DATA:
1538 tx_reg = AR5K_NOQCU_TXDP0;
1539 break;
1540 case AR5K_TX_QUEUE_BEACON:
1541 case AR5K_TX_QUEUE_CAB:
1542 tx_reg = AR5K_NOQCU_TXDP1;
1543 break;
1544 default:
1545 return -EINVAL;
1546 }
1547 } else {
1548 /*
1549 * Set the transmit queue descriptor pointer for
1550 * the selected queue on QCU for 5211+
1551 * (this won't work if the queue is still active)
1552 */
1553 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
1554 return -EIO;
1555
1556 tx_reg = AR5K_QUEUE_TXDP(queue);
1557 }
1558
1559 /* Set descriptor pointer */
1560 ath5k_hw_reg_write(ah, phys_addr, tx_reg);
1561
1562 return 0;
1563}
1564
1565/*
1566 * Update tx trigger level
1567 */
1568int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
1569{
1570 u32 trigger_level, imr;
1571 int ret = -EIO;
1572
1573 ATH5K_TRACE(ah->ah_sc);
1574
1575 /*
1576 * Disable interrupts by setting the mask
1577 */
1578 imr = ath5k_hw_set_intr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
1579
1580 /*TODO: Boundary check on trigger_level*/
1581 trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
1582 AR5K_TXCFG_TXFULL);
1583
1584 if (!increase) {
1585 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
1586 goto done;
1587 } else
1588 trigger_level +=
1589 ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
1590
1591 /*
1592 * Update trigger level on success
1593 */
1594 if (ah->ah_version == AR5K_AR5210)
1595 ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
1596 else
1597 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1598 AR5K_TXCFG_TXFULL, trigger_level);
1599
1600 ret = 0;
1601
1602done:
1603 /*
1604 * Restore interrupt mask
1605 */
1606 ath5k_hw_set_intr(ah, imr);
1607
1608 return ret;
1609}
1610
1611/*
1612 * Interrupt handling
1613 */
1614
1615/*
1616 * Check if we have pending interrupts
1617 */
1618bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
1619{
1620 ATH5K_TRACE(ah->ah_sc);
1621 return ath5k_hw_reg_read(ah, AR5K_INTPEND);
1622}
1623
1624/*
1625 * Get interrupt mask (ISR)
1626 */
1627int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
1628{
1629 u32 data;
1630
1631 ATH5K_TRACE(ah->ah_sc);
1632
1633 /*
1634 * Read interrupt status from the Interrupt Status register
1635 * on 5210
1636 */
1637 if (ah->ah_version == AR5K_AR5210) {
1638 data = ath5k_hw_reg_read(ah, AR5K_ISR);
1639 if (unlikely(data == AR5K_INT_NOCARD)) {
1640 *interrupt_mask = data;
1641 return -ENODEV;
1642 }
1643 } else {
1644 /*
1645 * Read interrupt status from the Read-And-Clear shadow register
1646 * Note: PISR/SISR Not available on 5210
1647 */
1648 data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
1649 }
1650
1651 /*
1652 * Get abstract interrupt mask (driver-compatible)
1653 */
1654 *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
1655
1656 if (unlikely(data == AR5K_INT_NOCARD))
1657 return -ENODEV;
1658
1659 if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR))
1660 *interrupt_mask |= AR5K_INT_RX;
1661
1662 if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR
1663 | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL))
1664 *interrupt_mask |= AR5K_INT_TX;
1665
1666 if (ah->ah_version != AR5K_AR5210) {
1667 /*HIU = Host Interface Unit (PCI etc)*/
1668 if (unlikely(data & (AR5K_ISR_HIUERR)))
1669 *interrupt_mask |= AR5K_INT_FATAL;
1670
1671 /*Beacon Not Ready*/
1672 if (unlikely(data & (AR5K_ISR_BNR)))
1673 *interrupt_mask |= AR5K_INT_BNR;
1674 }
1675
1676 /*
1677 * XXX: BMISS interrupts may occur after association.
1678 * I found this on 5210 code but it needs testing. If this is
1679 * true we should disable them before assoc and re-enable them
1680 * after a successfull assoc + some jiffies.
1681 */
1682#if 0
1683 interrupt_mask &= ~AR5K_INT_BMISS;
1684#endif
1685
1686 /*
1687 * In case we didn't handle anything,
1688 * print the register value.
1689 */
1690 if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
1691 ATH5K_PRINTF("0x%08x\n", data);
1692
1693 return 0;
1694}
1695
1696/*
1697 * Set interrupt mask
1698 */
1699enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask)
1700{
1701 enum ath5k_int old_mask, int_mask;
1702
1703 /*
1704 * Disable card interrupts to prevent any race conditions
1705 * (they will be re-enabled afterwards).
1706 */
1707 ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
1708 ath5k_hw_reg_read(ah, AR5K_IER);
1709
1710 old_mask = ah->ah_imr;
1711
1712 /*
1713 * Add additional, chipset-dependent interrupt mask flags
1714 * and write them to the IMR (interrupt mask register).
1715 */
1716 int_mask = new_mask & AR5K_INT_COMMON;
1717
1718 if (new_mask & AR5K_INT_RX)
1719 int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN |
1720 AR5K_IMR_RXDESC;
1721
1722 if (new_mask & AR5K_INT_TX)
1723 int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC |
1724 AR5K_IMR_TXURN;
1725
1726 if (ah->ah_version != AR5K_AR5210) {
1727 if (new_mask & AR5K_INT_FATAL) {
1728 int_mask |= AR5K_IMR_HIUERR;
1729 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT |
1730 AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR);
1731 }
1732 }
1733
1734 ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
1735
1736 /* Store new interrupt mask */
1737 ah->ah_imr = new_mask;
1738
1739 /* ..re-enable interrupts */
1740 ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
1741 ath5k_hw_reg_read(ah, AR5K_IER);
1742
1743 return old_mask;
1744}
1745
1746
1747/*************************\
1748 EEPROM access functions
1749\*************************/
1750
1751/*
1752 * Read from eeprom
1753 */
1754static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
1755{
1756 u32 status, timeout;
1757
1758 ATH5K_TRACE(ah->ah_sc);
1759 /*
1760 * Initialize EEPROM access
1761 */
1762 if (ah->ah_version == AR5K_AR5210) {
1763 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1764 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
1765 } else {
1766 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1767 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1768 AR5K_EEPROM_CMD_READ);
1769 }
1770
1771 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1772 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1773 if (status & AR5K_EEPROM_STAT_RDDONE) {
1774 if (status & AR5K_EEPROM_STAT_RDERR)
1775 return -EIO;
1776 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
1777 0xffff);
1778 return 0;
1779 }
1780 udelay(15);
1781 }
1782
1783 return -ETIMEDOUT;
1784}
1785
1786/*
1787 * Write to eeprom - currently disabled, use at your own risk
1788 */
1789#if 0
1790static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data)
1791{
1792
1793 u32 status, timeout;
1794
1795 ATH5K_TRACE(ah->ah_sc);
1796
1797 /*
1798 * Initialize eeprom access
1799 */
1800
1801 if (ah->ah_version == AR5K_AR5210) {
1802 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1803 } else {
1804 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1805 AR5K_EEPROM_CMD_RESET);
1806 }
1807
1808 /*
1809 * Write data to data register
1810 */
1811
1812 if (ah->ah_version == AR5K_AR5210) {
1813 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_BASE + (4 * offset));
1814 } else {
1815 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1816 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_DATA);
1817 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1818 AR5K_EEPROM_CMD_WRITE);
1819 }
1820
1821 /*
1822 * Check status
1823 */
1824
1825 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1826 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1827 if (status & AR5K_EEPROM_STAT_WRDONE) {
1828 if (status & AR5K_EEPROM_STAT_WRERR)
1829 return EIO;
1830 return 0;
1831 }
1832 udelay(15);
1833 }
1834
1835 ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!");
1836 return -EIO;
1837}
1838#endif
1839
1840/*
1841 * Translate binary channel representation in EEPROM to frequency
1842 */
1843static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, unsigned int mode)
1844{
1845 u16 val;
1846
1847 if (bin == AR5K_EEPROM_CHANNEL_DIS)
1848 return bin;
1849
1850 if (mode == AR5K_EEPROM_MODE_11A) {
1851 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1852 val = (5 * bin) + 4800;
1853 else
1854 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
1855 (bin * 10) + 5100;
1856 } else {
1857 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1858 val = bin + 2300;
1859 else
1860 val = bin + 2400;
1861 }
1862
1863 return val;
1864}
1865
1866/*
1867 * Read antenna infos from eeprom
1868 */
1869static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
1870 unsigned int mode)
1871{
1872 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1873 u32 o = *offset;
1874 u16 val;
1875 int ret, i = 0;
1876
1877 AR5K_EEPROM_READ(o++, val);
1878 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
1879 ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f;
1880 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1881
1882 AR5K_EEPROM_READ(o++, val);
1883 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1884 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1885 ee->ee_ant_control[mode][i++] = val & 0x3f;
1886
1887 AR5K_EEPROM_READ(o++, val);
1888 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
1889 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
1890 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
1891
1892 AR5K_EEPROM_READ(o++, val);
1893 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
1894 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
1895 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
1896 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1897
1898 AR5K_EEPROM_READ(o++, val);
1899 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1900 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1901 ee->ee_ant_control[mode][i++] = val & 0x3f;
1902
1903 /* Get antenna modes */
1904 ah->ah_antenna[mode][0] =
1905 (ee->ee_ant_control[mode][0] << 4) | 0x1;
1906 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
1907 ee->ee_ant_control[mode][1] |
1908 (ee->ee_ant_control[mode][2] << 6) |
1909 (ee->ee_ant_control[mode][3] << 12) |
1910 (ee->ee_ant_control[mode][4] << 18) |
1911 (ee->ee_ant_control[mode][5] << 24);
1912 ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
1913 ee->ee_ant_control[mode][6] |
1914 (ee->ee_ant_control[mode][7] << 6) |
1915 (ee->ee_ant_control[mode][8] << 12) |
1916 (ee->ee_ant_control[mode][9] << 18) |
1917 (ee->ee_ant_control[mode][10] << 24);
1918
1919 /* return new offset */
1920 *offset = o;
1921
1922 return 0;
1923}
1924
1925/*
1926 * Read supported modes from eeprom
1927 */
1928static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
1929 unsigned int mode)
1930{
1931 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1932 u32 o = *offset;
1933 u16 val;
1934 int ret;
1935
1936 AR5K_EEPROM_READ(o++, val);
1937 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
1938 ee->ee_thr_62[mode] = val & 0xff;
1939
1940 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1941 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
1942
1943 AR5K_EEPROM_READ(o++, val);
1944 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
1945 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
1946
1947 AR5K_EEPROM_READ(o++, val);
1948 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
1949
1950 if ((val & 0xff) & 0x80)
1951 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
1952 else
1953 ee->ee_noise_floor_thr[mode] = val & 0xff;
1954
1955 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1956 ee->ee_noise_floor_thr[mode] =
1957 mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
1958
1959 AR5K_EEPROM_READ(o++, val);
1960 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
1961 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
1962 ee->ee_xpd[mode] = val & 0x1;
1963
1964 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
1965 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
1966
1967 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
1968 AR5K_EEPROM_READ(o++, val);
1969 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
1970
1971 if (mode == AR5K_EEPROM_MODE_11A)
1972 ee->ee_xr_power[mode] = val & 0x3f;
1973 else {
1974 ee->ee_ob[mode][0] = val & 0x7;
1975 ee->ee_db[mode][0] = (val >> 3) & 0x7;
1976 }
1977 }
1978
1979 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
1980 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
1981 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
1982 } else {
1983 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
1984
1985 AR5K_EEPROM_READ(o++, val);
1986 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
1987
1988 if (mode == AR5K_EEPROM_MODE_11G)
1989 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
1990 }
1991
1992 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
1993 mode == AR5K_EEPROM_MODE_11A) {
1994 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
1995 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
1996 }
1997
1998 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
1999 mode == AR5K_EEPROM_MODE_11G)
2000 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
2001
2002 /* return new offset */
2003 *offset = o;
2004
2005 return 0;
2006}
2007
2008/*
2009 * Initialize eeprom & capabilities structs
2010 */
2011static int ath5k_eeprom_init(struct ath5k_hw *ah)
2012{
2013 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2014 unsigned int mode, i;
2015 int ret;
2016 u32 offset;
2017 u16 val;
2018
2019 /* Initial TX thermal adjustment values */
2020 ee->ee_tx_clip = 4;
2021 ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
2022 ee->ee_gain_select = 1;
2023
2024 /*
2025 * Read values from EEPROM and store them in the capability structure
2026 */
2027 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
2028 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
2029 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
2030 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
2031 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
2032
2033 /* Return if we have an old EEPROM */
2034 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
2035 return 0;
2036
2037#ifdef notyet
2038 /*
2039 * Validate the checksum of the EEPROM date. There are some
2040 * devices with invalid EEPROMs.
2041 */
2042 for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
2043 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
2044 cksum ^= val;
2045 }
2046 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
2047 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
2048 return -EIO;
2049 }
2050#endif
2051
2052 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
2053 ee_ant_gain);
2054
2055 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2056 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
2057 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
2058 }
2059
2060 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
2061 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
2062 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
2063 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
2064
2065 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
2066 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
2067 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
2068 }
2069
2070 /*
2071 * Get conformance test limit values
2072 */
2073 offset = AR5K_EEPROM_CTL(ah->ah_ee_version);
2074 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version);
2075
2076 for (i = 0; i < ee->ee_ctls; i++) {
2077 AR5K_EEPROM_READ(offset++, val);
2078 ee->ee_ctl[i] = (val >> 8) & 0xff;
2079 ee->ee_ctl[i + 1] = val & 0xff;
2080 }
2081
2082 /*
2083 * Get values for 802.11a (5GHz)
2084 */
2085 mode = AR5K_EEPROM_MODE_11A;
2086
2087 ee->ee_turbo_max_power[mode] =
2088 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
2089
2090 offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
2091
2092 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2093 if (ret)
2094 return ret;
2095
2096 AR5K_EEPROM_READ(offset++, val);
2097 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2098 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
2099 ee->ee_db[mode][3] = (val >> 2) & 0x7;
2100 ee->ee_ob[mode][2] = (val << 1) & 0x7;
2101
2102 AR5K_EEPROM_READ(offset++, val);
2103 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
2104 ee->ee_db[mode][2] = (val >> 12) & 0x7;
2105 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
2106 ee->ee_db[mode][1] = (val >> 6) & 0x7;
2107 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
2108 ee->ee_db[mode][0] = val & 0x7;
2109
2110 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2111 if (ret)
2112 return ret;
2113
2114 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
2115 AR5K_EEPROM_READ(offset++, val);
2116 ee->ee_margin_tx_rx[mode] = val & 0x3f;
2117 }
2118
2119 /*
2120 * Get values for 802.11b (2.4GHz)
2121 */
2122 mode = AR5K_EEPROM_MODE_11B;
2123 offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
2124
2125 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2126 if (ret)
2127 return ret;
2128
2129 AR5K_EEPROM_READ(offset++, val);
2130 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2131 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
2132 ee->ee_db[mode][1] = val & 0x7;
2133
2134 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2135 if (ret)
2136 return ret;
2137
2138 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2139 AR5K_EEPROM_READ(offset++, val);
2140 ee->ee_cal_pier[mode][0] =
2141 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2142 ee->ee_cal_pier[mode][1] =
2143 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
2144
2145 AR5K_EEPROM_READ(offset++, val);
2146 ee->ee_cal_pier[mode][2] =
2147 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2148 }
2149
2150 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
2151 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
2152
2153 /*
2154 * Get values for 802.11g (2.4GHz)
2155 */
2156 mode = AR5K_EEPROM_MODE_11G;
2157 offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
2158
2159 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
2160 if (ret)
2161 return ret;
2162
2163 AR5K_EEPROM_READ(offset++, val);
2164 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
2165 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
2166 ee->ee_db[mode][1] = val & 0x7;
2167
2168 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
2169 if (ret)
2170 return ret;
2171
2172 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
2173 AR5K_EEPROM_READ(offset++, val);
2174 ee->ee_cal_pier[mode][0] =
2175 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2176 ee->ee_cal_pier[mode][1] =
2177 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
2178
2179 AR5K_EEPROM_READ(offset++, val);
2180 ee->ee_turbo_max_power[mode] = val & 0x7f;
2181 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
2182
2183 AR5K_EEPROM_READ(offset++, val);
2184 ee->ee_cal_pier[mode][2] =
2185 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
2186
2187 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
2188 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
2189
2190 AR5K_EEPROM_READ(offset++, val);
2191 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
2192 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
2193
2194 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
2195 AR5K_EEPROM_READ(offset++, val);
2196 ee->ee_cck_ofdm_gain_delta = val & 0xff;
2197 }
2198 }
2199
2200 /*
2201 * Read 5GHz EEPROM channels
2202 */
2203
2204 return 0;
2205}
2206
2207/*
2208 * Read the MAC address from eeprom
2209 */
2210static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
2211{
2212 u8 mac_d[ETH_ALEN];
2213 u32 total, offset;
2214 u16 data;
2215 int octet, ret;
2216
2217 memset(mac, 0, ETH_ALEN);
2218 memset(mac_d, 0, ETH_ALEN);
2219
2220 ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
2221 if (ret)
2222 return ret;
2223
2224 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
2225 ret = ath5k_hw_eeprom_read(ah, offset, &data);
2226 if (ret)
2227 return ret;
2228
2229 total += data;
2230 mac_d[octet + 1] = data & 0xff;
2231 mac_d[octet] = data >> 8;
2232 octet += 2;
2233 }
2234
2235 memcpy(mac, mac_d, ETH_ALEN);
2236
2237 if (!total || total == 3 * 0xffff)
2238 return -EINVAL;
2239
2240 return 0;
2241}
2242
2243/*
2244 * Fill the capabilities struct
2245 */
2246static int ath5k_hw_get_capabilities(struct ath5k_hw *ah)
2247{
2248 u16 ee_header;
2249
2250 ATH5K_TRACE(ah->ah_sc);
2251 /* Capabilities stored in the EEPROM */
2252 ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
2253
2254 if (ah->ah_version == AR5K_AR5210) {
2255 /*
2256 * Set radio capabilities
2257 * (The AR5110 only supports the middle 5GHz band)
2258 */
2259 ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
2260 ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
2261 ah->ah_capabilities.cap_range.range_2ghz_min = 0;
2262 ah->ah_capabilities.cap_range.range_2ghz_max = 0;
2263
2264 /* Set supported modes */
2265 __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
2266 __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
2267 } else {
2268 /*
2269 * XXX The tranceiver supports frequencies from 4920 to 6100GHz
2270 * XXX and from 2312 to 2732GHz. There are problems with the
2271 * XXX current ieee80211 implementation because the IEEE
2272 * XXX channel mapping does not support negative channel
2273 * XXX numbers (2312MHz is channel -19). Of course, this
2274 * XXX doesn't matter because these channels are out of range
2275 * XXX but some regulation domains like MKK (Japan) will
2276 * XXX support frequencies somewhere around 4.8GHz.
2277 */
2278
2279 /*
2280 * Set radio capabilities
2281 */
2282
2283 if (AR5K_EEPROM_HDR_11A(ee_header)) {
2284 ah->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
2285 ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
2286
2287 /* Set supported modes */
2288 __set_bit(AR5K_MODE_11A,
2289 ah->ah_capabilities.cap_mode);
2290 __set_bit(AR5K_MODE_11A_TURBO,
2291 ah->ah_capabilities.cap_mode);
2292 if (ah->ah_version == AR5K_AR5212)
2293 __set_bit(AR5K_MODE_11G_TURBO,
2294 ah->ah_capabilities.cap_mode);
2295 }
2296
2297 /* Enable 802.11b if a 2GHz capable radio (2111/5112) is
2298 * connected */
2299 if (AR5K_EEPROM_HDR_11B(ee_header) ||
2300 AR5K_EEPROM_HDR_11G(ee_header)) {
2301 ah->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
2302 ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
2303
2304 if (AR5K_EEPROM_HDR_11B(ee_header))
2305 __set_bit(AR5K_MODE_11B,
2306 ah->ah_capabilities.cap_mode);
2307
2308 if (AR5K_EEPROM_HDR_11G(ee_header))
2309 __set_bit(AR5K_MODE_11G,
2310 ah->ah_capabilities.cap_mode);
2311 }
2312 }
2313
2314 /* GPIO */
2315 ah->ah_gpio_npins = AR5K_NUM_GPIO;
2316
2317 /* Set number of supported TX queues */
2318 if (ah->ah_version == AR5K_AR5210)
2319 ah->ah_capabilities.cap_queues.q_tx_num =
2320 AR5K_NUM_TX_QUEUES_NOQCU;
2321 else
2322 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
2323
2324 return 0;
2325}
2326
2327/*********************************\
2328 Protocol Control Unit Functions
2329\*********************************/
2330
2331/*
2332 * Set Operation mode
2333 */
2334int ath5k_hw_set_opmode(struct ath5k_hw *ah)
2335{
2336 u32 pcu_reg, beacon_reg, low_id, high_id;
2337
2338 pcu_reg = 0;
2339 beacon_reg = 0;
2340
2341 ATH5K_TRACE(ah->ah_sc);
2342
2343 switch (ah->ah_op_mode) {
2344 case IEEE80211_IF_TYPE_IBSS:
2345 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA |
2346 (ah->ah_version == AR5K_AR5210 ?
2347 AR5K_STA_ID1_NO_PSPOLL : 0);
2348 beacon_reg |= AR5K_BCR_ADHOC;
2349 break;
2350
2351 case IEEE80211_IF_TYPE_AP:
2352 case IEEE80211_IF_TYPE_MESH_POINT:
2353 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA |
2354 (ah->ah_version == AR5K_AR5210 ?
2355 AR5K_STA_ID1_NO_PSPOLL : 0);
2356 beacon_reg |= AR5K_BCR_AP;
2357 break;
2358
2359 case IEEE80211_IF_TYPE_STA:
2360 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2361 (ah->ah_version == AR5K_AR5210 ?
2362 AR5K_STA_ID1_PWR_SV : 0);
2363 case IEEE80211_IF_TYPE_MNTR:
2364 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2365 (ah->ah_version == AR5K_AR5210 ?
2366 AR5K_STA_ID1_NO_PSPOLL : 0);
2367 break;
2368
2369 default:
2370 return -EINVAL;
2371 }
2372
2373 /*
2374 * Set PCU registers
2375 */
2376 low_id = AR5K_LOW_ID(ah->ah_sta_id);
2377 high_id = AR5K_HIGH_ID(ah->ah_sta_id);
2378 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2379 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
2380
2381 /*
2382 * Set Beacon Control Register on 5210
2383 */
2384 if (ah->ah_version == AR5K_AR5210)
2385 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
2386
2387 return 0;
2388}
2389
2390/*
2391 * BSSID Functions
2392 */
2393
2394/*
2395 * Get station id
2396 */
2397void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
2398{
2399 ATH5K_TRACE(ah->ah_sc);
2400 memcpy(mac, ah->ah_sta_id, ETH_ALEN);
2401}
2402
2403/*
2404 * Set station id
2405 */
2406int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
2407{
2408 u32 low_id, high_id;
2409
2410 ATH5K_TRACE(ah->ah_sc);
2411 /* Set new station ID */
2412 memcpy(ah->ah_sta_id, mac, ETH_ALEN);
2413
2414 low_id = AR5K_LOW_ID(mac);
2415 high_id = AR5K_HIGH_ID(mac);
2416
2417 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2418 ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1);
2419
2420 return 0;
2421}
2422
2423/*
2424 * Set BSSID
2425 */
2426void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
2427{
2428 u32 low_id, high_id;
2429 u16 tim_offset = 0;
2430
2431 /*
2432 * Set simple BSSID mask on 5212
2433 */
2434 if (ah->ah_version == AR5K_AR5212) {
2435 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0);
2436 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1);
2437 }
2438
2439 /*
2440 * Set BSSID which triggers the "SME Join" operation
2441 */
2442 low_id = AR5K_LOW_ID(bssid);
2443 high_id = AR5K_HIGH_ID(bssid);
2444 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
2445 ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
2446 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
2447
2448 if (assoc_id == 0) {
2449 ath5k_hw_disable_pspoll(ah);
2450 return;
2451 }
2452
2453 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
2454 tim_offset ? tim_offset + 4 : 0);
2455
2456 ath5k_hw_enable_pspoll(ah, NULL, 0);
2457}
2458/**
2459 * ath5k_hw_set_bssid_mask - set common bits we should listen to
2460 *
2461 * The bssid_mask is a utility used by AR5212 hardware to inform the hardware
2462 * which bits of the interface's MAC address should be looked at when trying
2463 * to decide which packets to ACK. In station mode every bit matters. In AP
2464 * mode with a single BSS every bit matters as well. In AP mode with
2465 * multiple BSSes not every bit matters.
2466 *
2467 * @ah: the &struct ath5k_hw
2468 * @mask: the bssid_mask, a u8 array of size ETH_ALEN
2469 *
2470 * Note that this is a simple filter and *does* not filter out all
2471 * relevant frames. Some non-relevant frames will get through, probability
2472 * jocks are welcomed to compute.
2473 *
2474 * When handling multiple BSSes (or VAPs) you can get the BSSID mask by
2475 * computing the set of:
2476 *
2477 * ~ ( MAC XOR BSSID )
2478 *
2479 * When you do this you are essentially computing the common bits. Later it
2480 * is assumed the harware will "and" (&) the BSSID mask with the MAC address
2481 * to obtain the relevant bits which should match on the destination frame.
2482 *
2483 * Simple example: on your card you have have two BSSes you have created with
2484 * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
2485 * There is another BSSID-03 but you are not part of it. For simplicity's sake,
2486 * assuming only 4 bits for a mac address and for BSSIDs you can then have:
2487 *
2488 * \
2489 * MAC: 0001 |
2490 * BSSID-01: 0100 | --> Belongs to us
2491 * BSSID-02: 1001 |
2492 * /
2493 * -------------------
2494 * BSSID-03: 0110 | --> External
2495 * -------------------
2496 *
2497 * Our bssid_mask would then be:
2498 *
2499 * On loop iteration for BSSID-01:
2500 * ~(0001 ^ 0100) -> ~(0101)
2501 * -> 1010
2502 * bssid_mask = 1010
2503 *
2504 * On loop iteration for BSSID-02:
2505 * bssid_mask &= ~(0001 ^ 1001)
2506 * bssid_mask = (1010) & ~(0001 ^ 1001)
2507 * bssid_mask = (1010) & ~(1001)
2508 * bssid_mask = (1010) & (0110)
2509 * bssid_mask = 0010
2510 *
2511 * A bssid_mask of 0010 means "only pay attention to the second least
2512 * significant bit". This is because its the only bit common
2513 * amongst the MAC and all BSSIDs we support. To findout what the real
2514 * common bit is we can simply "&" the bssid_mask now with any BSSID we have
2515 * or our MAC address (we assume the hardware uses the MAC address).
2516 *
2517 * Now, suppose there's an incoming frame for BSSID-03:
2518 *
2519 * IFRAME-01: 0110
2520 *
2521 * An easy eye-inspeciton of this already should tell you that this frame
2522 * will not pass our check. This is beacuse the bssid_mask tells the
2523 * hardware to only look at the second least significant bit and the
2524 * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
2525 * as 1, which does not match 0.
2526 *
2527 * So with IFRAME-01 we *assume* the hardware will do:
2528 *
2529 * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2530 * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
2531 * --> allow = (0010) == 0000 ? 1 : 0;
2532 * --> allow = 0
2533 *
2534 * Lets now test a frame that should work:
2535 *
2536 * IFRAME-02: 0001 (we should allow)
2537 *
2538 * allow = (0001 & 1010) == 1010
2539 *
2540 * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2541 * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
2542 * --> allow = (0010) == (0010)
2543 * --> allow = 1
2544 *
2545 * Other examples:
2546 *
2547 * IFRAME-03: 0100 --> allowed
2548 * IFRAME-04: 1001 --> allowed
2549 * IFRAME-05: 1101 --> allowed but its not for us!!!
2550 *
2551 */
2552int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
2553{
2554 u32 low_id, high_id;
2555 ATH5K_TRACE(ah->ah_sc);
2556
2557 if (ah->ah_version == AR5K_AR5212) {
2558 low_id = AR5K_LOW_ID(mask);
2559 high_id = AR5K_HIGH_ID(mask);
2560
2561 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
2562 ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
2563
2564 return 0;
2565 }
2566
2567 return -EIO;
2568}
2569
2570/*
2571 * Receive start/stop functions
2572 */
2573
2574/*
2575 * Start receive on PCU
2576 */
2577void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
2578{
2579 ATH5K_TRACE(ah->ah_sc);
2580 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
2581
2582 /* TODO: ANI Support */
2583}
2584
2585/*
2586 * Stop receive on PCU
2587 */
2588void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah)
2589{
2590 ATH5K_TRACE(ah->ah_sc);
2591 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
2592
2593 /* TODO: ANI Support */
2594}
2595
2596/*
2597 * RX Filter functions
2598 */
2599
2600/*
2601 * Set multicast filter
2602 */
2603void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
2604{
2605 ATH5K_TRACE(ah->ah_sc);
2606 /* Set the multicat filter */
2607 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
2608 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
2609}
2610
2611/*
2612 * Set multicast filter by index
2613 */
2614int ath5k_hw_set_mcast_filterindex(struct ath5k_hw *ah, u32 index)
2615{
2616
2617 ATH5K_TRACE(ah->ah_sc);
2618 if (index >= 64)
2619 return -EINVAL;
2620 else if (index >= 32)
2621 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
2622 (1 << (index - 32)));
2623 else
2624 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2625
2626 return 0;
2627}
2628
2629/*
2630 * Clear Multicast filter by index
2631 */
2632int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
2633{
2634
2635 ATH5K_TRACE(ah->ah_sc);
2636 if (index >= 64)
2637 return -EINVAL;
2638 else if (index >= 32)
2639 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
2640 (1 << (index - 32)));
2641 else
2642 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2643
2644 return 0;
2645}
2646
2647/*
2648 * Get current rx filter
2649 */
2650u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
2651{
2652 u32 data, filter = 0;
2653
2654 ATH5K_TRACE(ah->ah_sc);
2655 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
2656
2657 /*Radar detection for 5212*/
2658 if (ah->ah_version == AR5K_AR5212) {
2659 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
2660
2661 if (data & AR5K_PHY_ERR_FIL_RADAR)
2662 filter |= AR5K_RX_FILTER_RADARERR;
2663 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
2664 filter |= AR5K_RX_FILTER_PHYERR;
2665 }
2666
2667 return filter;
2668}
2669
2670/*
2671 * Set rx filter
2672 */
2673void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
2674{
2675 u32 data = 0;
2676
2677 ATH5K_TRACE(ah->ah_sc);
2678
2679 /* Set PHY error filter register on 5212*/
2680 if (ah->ah_version == AR5K_AR5212) {
2681 if (filter & AR5K_RX_FILTER_RADARERR)
2682 data |= AR5K_PHY_ERR_FIL_RADAR;
2683 if (filter & AR5K_RX_FILTER_PHYERR)
2684 data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
2685 }
2686
2687 /*
2688 * The AR5210 uses promiscous mode to detect radar activity
2689 */
2690 if (ah->ah_version == AR5K_AR5210 &&
2691 (filter & AR5K_RX_FILTER_RADARERR)) {
2692 filter &= ~AR5K_RX_FILTER_RADARERR;
2693 filter |= AR5K_RX_FILTER_PROM;
2694 }
2695
2696 /*Zero length DMA*/
2697 if (data)
2698 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2699 else
2700 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2701
2702 /*Write RX Filter register*/
2703 ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
2704
2705 /*Write PHY error filter register on 5212*/
2706 if (ah->ah_version == AR5K_AR5212)
2707 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
2708
2709}
2710
2711/*
2712 * Beacon related functions
2713 */
2714
2715/*
2716 * Get a 32bit TSF
2717 */
2718u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
2719{
2720 ATH5K_TRACE(ah->ah_sc);
2721 return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
2722}
2723
2724/*
2725 * Get the full 64bit TSF
2726 */
2727u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
2728{
2729 u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
2730 ATH5K_TRACE(ah->ah_sc);
2731
2732 return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
2733}
2734
2735/*
2736 * Force a TSF reset
2737 */
2738void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
2739{
2740 ATH5K_TRACE(ah->ah_sc);
2741 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF);
2742}
2743
2744/*
2745 * Initialize beacon timers
2746 */
2747void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
2748{
2749 u32 timer1, timer2, timer3;
2750
2751 ATH5K_TRACE(ah->ah_sc);
2752 /*
2753 * Set the additional timers by mode
2754 */
2755 switch (ah->ah_op_mode) {
2756 case IEEE80211_IF_TYPE_STA:
2757 if (ah->ah_version == AR5K_AR5210) {
2758 timer1 = 0xffffffff;
2759 timer2 = 0xffffffff;
2760 } else {
2761 timer1 = 0x0000ffff;
2762 timer2 = 0x0007ffff;
2763 }
2764 break;
2765
2766 default:
2767 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
2768 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
2769 }
2770
2771 timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
2772
2773 /*
2774 * Set the beacon register and enable all timers.
2775 * (next beacon, DMA beacon, software beacon, ATIM window time)
2776 */
2777 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
2778 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
2779 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
2780 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
2781
2782 ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
2783 AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE),
2784 AR5K_BEACON);
2785}
2786
2787#if 0
2788/*
2789 * Set beacon timers
2790 */
2791int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
2792 const struct ath5k_beacon_state *state)
2793{
2794 u32 cfp_period, next_cfp, dtim, interval, next_beacon;
2795
2796 /*
2797 * TODO: should be changed through *state
2798 * review struct ath5k_beacon_state struct
2799 *
2800 * XXX: These are used for cfp period bellow, are they
2801 * ok ? Is it O.K. for tsf here to be 0 or should we use
2802 * get_tsf ?
2803 */
2804 u32 dtim_count = 0; /* XXX */
2805 u32 cfp_count = 0; /* XXX */
2806 u32 tsf = 0; /* XXX */
2807
2808 ATH5K_TRACE(ah->ah_sc);
2809 /* Return on an invalid beacon state */
2810 if (state->bs_interval < 1)
2811 return -EINVAL;
2812
2813 interval = state->bs_interval;
2814 dtim = state->bs_dtim_period;
2815
2816 /*
2817 * PCF support?
2818 */
2819 if (state->bs_cfp_period > 0) {
2820 /*
2821 * Enable PCF mode and set the CFP
2822 * (Contention Free Period) and timer registers
2823 */
2824 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
2825 state->bs_interval;
2826 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
2827 state->bs_interval;
2828
2829 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
2830 AR5K_STA_ID1_DEFAULT_ANTENNA |
2831 AR5K_STA_ID1_PCF);
2832 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
2833 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
2834 AR5K_CFP_DUR);
2835 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
2836 next_cfp)) << 3, AR5K_TIMER2);
2837 } else {
2838 /* Disable PCF mode */
2839 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2840 AR5K_STA_ID1_DEFAULT_ANTENNA |
2841 AR5K_STA_ID1_PCF);
2842 }
2843
2844 /*
2845 * Enable the beacon timer register
2846 */
2847 ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
2848
2849 /*
2850 * Start the beacon timers
2851 */
2852 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &~
2853 (AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
2854 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
2855 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
2856 AR5K_BEACON_PERIOD), AR5K_BEACON);
2857
2858 /*
2859 * Write new beacon miss threshold, if it appears to be valid
2860 * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
2861 * and return if its not in range. We can test this by reading value and
2862 * setting value to a largest value and seeing which values register.
2863 */
2864
2865 AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
2866 state->bs_bmiss_threshold);
2867
2868 /*
2869 * Set sleep control register
2870 * XXX: Didn't find this in 5210 code but since this register
2871 * exists also in ar5k's 5210 headers i leave it as common code.
2872 */
2873 AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
2874 (state->bs_sleep_duration - 3) << 3);
2875
2876 /*
2877 * Set enhanced sleep registers on 5212
2878 */
2879 if (ah->ah_version == AR5K_AR5212) {
2880 if (state->bs_sleep_duration > state->bs_interval &&
2881 roundup(state->bs_sleep_duration, interval) ==
2882 state->bs_sleep_duration)
2883 interval = state->bs_sleep_duration;
2884
2885 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
2886 roundup(state->bs_sleep_duration, dtim) ==
2887 state->bs_sleep_duration))
2888 dtim = state->bs_sleep_duration;
2889
2890 if (interval > dtim)
2891 return -EINVAL;
2892
2893 next_beacon = interval == dtim ? state->bs_next_dtim :
2894 state->bs_next_beacon;
2895
2896 ath5k_hw_reg_write(ah,
2897 AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
2898 AR5K_SLEEP0_NEXT_DTIM) |
2899 AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
2900 AR5K_SLEEP0_ENH_SLEEP_EN |
2901 AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
2902
2903 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
2904 AR5K_SLEEP1_NEXT_TIM) |
2905 AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
2906
2907 ath5k_hw_reg_write(ah,
2908 AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
2909 AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
2910 }
2911
2912 return 0;
2913}
2914
2915/*
2916 * Reset beacon timers
2917 */
2918void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
2919{
2920 ATH5K_TRACE(ah->ah_sc);
2921 /*
2922 * Disable beacon timer
2923 */
2924 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
2925
2926 /*
2927 * Disable some beacon register values
2928 */
2929 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2930 AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
2931 ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
2932}
2933
2934/*
2935 * Wait for beacon queue to finish
2936 */
2937int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
2938{
2939 unsigned int i;
2940 int ret;
2941
2942 ATH5K_TRACE(ah->ah_sc);
2943
2944 /* 5210 doesn't have QCU*/
2945 if (ah->ah_version == AR5K_AR5210) {
2946 /*
2947 * Wait for beaconn queue to finish by checking
2948 * Control Register and Beacon Status Register.
2949 */
2950 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
2951 if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
2952 ||
2953 !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
2954 break;
2955 udelay(10);
2956 }
2957
2958 /* Timeout... */
2959 if (i <= 0) {
2960 /*
2961 * Re-schedule the beacon queue
2962 */
2963 ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
2964 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
2965 AR5K_BCR);
2966
2967 return -EIO;
2968 }
2969 ret = 0;
2970 } else {
2971 /*5211/5212*/
2972 ret = ath5k_hw_register_timeout(ah,
2973 AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
2974 AR5K_QCU_STS_FRMPENDCNT, 0, false);
2975
2976 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
2977 return -EIO;
2978 }
2979
2980 return ret;
2981}
2982#endif
2983
2984/*
2985 * Update mib counters (statistics)
2986 */
2987void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
2988 struct ieee80211_low_level_stats *stats)
2989{
2990 ATH5K_TRACE(ah->ah_sc);
2991
2992 /* Read-And-Clear */
2993 stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
2994 stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
2995 stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
2996 stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
2997
2998 /* XXX: Should we use this to track beacon count ?
2999 * -we read it anyway to clear the register */
3000 ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
3001
3002 /* Reset profile count registers on 5212*/
3003 if (ah->ah_version == AR5K_AR5212) {
3004 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
3005 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
3006 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
3007 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
3008 }
3009}
3010
3011/** ath5k_hw_set_ack_bitrate - set bitrate for ACKs
3012 *
3013 * @ah: the &struct ath5k_hw
3014 * @high: determines if to use low bit rate or now
3015 */
3016void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
3017{
3018 if (ah->ah_version != AR5K_AR5212)
3019 return;
3020 else {
3021 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
3022 if (high)
3023 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
3024 else
3025 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
3026 }
3027}
3028
3029
3030/*
3031 * ACK/CTS Timeouts
3032 */
3033
3034/*
3035 * Set ACK timeout on PCU
3036 */
3037int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
3038{
3039 ATH5K_TRACE(ah->ah_sc);
3040 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
3041 ah->ah_turbo) <= timeout)
3042 return -EINVAL;
3043
3044 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
3045 ath5k_hw_htoclock(timeout, ah->ah_turbo));
3046
3047 return 0;
3048}
3049
3050/*
3051 * Read the ACK timeout from PCU
3052 */
3053unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
3054{
3055 ATH5K_TRACE(ah->ah_sc);
3056
3057 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
3058 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
3059}
3060
3061/*
3062 * Set CTS timeout on PCU
3063 */
3064int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
3065{
3066 ATH5K_TRACE(ah->ah_sc);
3067 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
3068 ah->ah_turbo) <= timeout)
3069 return -EINVAL;
3070
3071 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
3072 ath5k_hw_htoclock(timeout, ah->ah_turbo));
3073
3074 return 0;
3075}
3076
3077/*
3078 * Read CTS timeout from PCU
3079 */
3080unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
3081{
3082 ATH5K_TRACE(ah->ah_sc);
3083 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
3084 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
3085}
3086
3087/*
3088 * Key table (WEP) functions
3089 */
3090
3091int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
3092{
3093 unsigned int i;
3094
3095 ATH5K_TRACE(ah->ah_sc);
3096 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3097
3098 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
3099 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
3100
3101 /*
3102 * Set NULL encryption on AR5212+
3103 *
3104 * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
3105 * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
3106 *
3107 * Note2: Windows driver (ndiswrapper) sets this to
3108 * 0x00000714 instead of 0x00000007
3109 */
3110 if (ah->ah_version > AR5K_AR5211)
3111 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
3112 AR5K_KEYTABLE_TYPE(entry));
3113
3114 return 0;
3115}
3116
3117int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
3118{
3119 ATH5K_TRACE(ah->ah_sc);
3120 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3121
3122 /* Check the validation flag at the end of the entry */
3123 return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
3124 AR5K_KEYTABLE_VALID;
3125}
3126
3127int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
3128 const struct ieee80211_key_conf *key, const u8 *mac)
3129{
3130 unsigned int i;
3131 __le32 key_v[5] = {};
3132 u32 keytype;
3133
3134 ATH5K_TRACE(ah->ah_sc);
3135
3136 /* key->keylen comes in from mac80211 in bytes */
3137
3138 if (key->keylen > AR5K_KEYTABLE_SIZE / 8)
3139 return -EOPNOTSUPP;
3140
3141 switch (key->keylen) {
3142 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */
3143 case 40 / 8:
3144 memcpy(&key_v[0], key->key, 5);
3145 keytype = AR5K_KEYTABLE_TYPE_40;
3146 break;
3147
3148 /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */
3149 case 104 / 8:
3150 memcpy(&key_v[0], &key->key[0], 6);
3151 memcpy(&key_v[2], &key->key[6], 6);
3152 memcpy(&key_v[4], &key->key[12], 1);
3153 keytype = AR5K_KEYTABLE_TYPE_104;
3154 break;
3155 /* WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */
3156 case 128 / 8:
3157 memcpy(&key_v[0], &key->key[0], 6);
3158 memcpy(&key_v[2], &key->key[6], 6);
3159 memcpy(&key_v[4], &key->key[12], 4);
3160 keytype = AR5K_KEYTABLE_TYPE_128;
3161 break;
3162
3163 default:
3164 return -EINVAL; /* shouldn't happen */
3165 }
3166
3167 for (i = 0; i < ARRAY_SIZE(key_v); i++)
3168 ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
3169 AR5K_KEYTABLE_OFF(entry, i));
3170
3171 ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
3172
3173 return ath5k_hw_set_key_lladdr(ah, entry, mac);
3174}
3175
3176int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
3177{
3178 u32 low_id, high_id;
3179
3180 ATH5K_TRACE(ah->ah_sc);
3181 /* Invalid entry (key table overflow) */
3182 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3183
3184 /* MAC may be NULL if it's a broadcast key. In this case no need to
3185 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
3186 if (unlikely(mac == NULL)) {
3187 low_id = 0xffffffff;
3188 high_id = 0xffff | AR5K_KEYTABLE_VALID;
3189 } else {
3190 low_id = AR5K_LOW_ID(mac);
3191 high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
3192 }
3193
3194 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
3195 ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
3196
3197 return 0;
3198}
3199
3200
3201/********************************************\
3202Queue Control Unit, DFS Control Unit Functions
3203\********************************************/
3204
3205/*
3206 * Initialize a transmit queue
3207 */
3208int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
3209 struct ath5k_txq_info *queue_info)
3210{
3211 unsigned int queue;
3212 int ret;
3213
3214 ATH5K_TRACE(ah->ah_sc);
3215
3216 /*
3217 * Get queue by type
3218 */
3219 /*5210 only has 2 queues*/
3220 if (ah->ah_version == AR5K_AR5210) {
3221 switch (queue_type) {
3222 case AR5K_TX_QUEUE_DATA:
3223 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
3224 break;
3225 case AR5K_TX_QUEUE_BEACON:
3226 case AR5K_TX_QUEUE_CAB:
3227 queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
3228 break;
3229 default:
3230 return -EINVAL;
3231 }
3232 } else {
3233 switch (queue_type) {
3234 case AR5K_TX_QUEUE_DATA:
3235 for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
3236 ah->ah_txq[queue].tqi_type !=
3237 AR5K_TX_QUEUE_INACTIVE; queue++) {
3238
3239 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
3240 return -EINVAL;
3241 }
3242 break;
3243 case AR5K_TX_QUEUE_UAPSD:
3244 queue = AR5K_TX_QUEUE_ID_UAPSD;
3245 break;
3246 case AR5K_TX_QUEUE_BEACON:
3247 queue = AR5K_TX_QUEUE_ID_BEACON;
3248 break;
3249 case AR5K_TX_QUEUE_CAB:
3250 queue = AR5K_TX_QUEUE_ID_CAB;
3251 break;
3252 case AR5K_TX_QUEUE_XR_DATA:
3253 if (ah->ah_version != AR5K_AR5212)
3254 ATH5K_ERR(ah->ah_sc,
3255 "XR data queues only supported in"
3256 " 5212!\n");
3257 queue = AR5K_TX_QUEUE_ID_XR_DATA;
3258 break;
3259 default:
3260 return -EINVAL;
3261 }
3262 }
3263
3264 /*
3265 * Setup internal queue structure
3266 */
3267 memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
3268 ah->ah_txq[queue].tqi_type = queue_type;
3269
3270 if (queue_info != NULL) {
3271 queue_info->tqi_type = queue_type;
3272 ret = ath5k_hw_setup_tx_queueprops(ah, queue, queue_info);
3273 if (ret)
3274 return ret;
3275 }
3276 /*
3277 * We use ah_txq_status to hold a temp value for
3278 * the Secondary interrupt mask registers on 5211+
3279 * check out ath5k_hw_reset_tx_queue
3280 */
3281 AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
3282
3283 return queue;
3284}
3285
3286/*
3287 * Setup a transmit queue
3288 */
3289int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue,
3290 const struct ath5k_txq_info *queue_info)
3291{
3292 ATH5K_TRACE(ah->ah_sc);
3293 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3294
3295 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3296 return -EIO;
3297
3298 memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
3299
3300 /*XXX: Is this supported on 5210 ?*/
3301 if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
3302 ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
3303 (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
3304 queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
3305 ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
3306
3307 return 0;
3308}
3309
3310/*
3311 * Get properties for a specific transmit queue
3312 */
3313int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
3314 struct ath5k_txq_info *queue_info)
3315{
3316 ATH5K_TRACE(ah->ah_sc);
3317 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
3318 return 0;
3319}
3320
3321/*
3322 * Set a transmit queue inactive
3323 */
3324void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3325{
3326 ATH5K_TRACE(ah->ah_sc);
3327 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
3328 return;
3329
3330 /* This queue will be skipped in further operations */
3331 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
3332 /*For SIMR setup*/
3333 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
3334}
3335
3336/*
3337 * Set DFS params for a transmit queue
3338 */
3339int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3340{
3341 u32 cw_min, cw_max, retry_lg, retry_sh;
3342 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
3343
3344 ATH5K_TRACE(ah->ah_sc);
3345 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3346
3347 tq = &ah->ah_txq[queue];
3348
3349 if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
3350 return 0;
3351
3352 if (ah->ah_version == AR5K_AR5210) {
3353 /* Only handle data queues, others will be ignored */
3354 if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
3355 return 0;
3356
3357 /* Set Slot time */
3358 ath5k_hw_reg_write(ah, ah->ah_turbo ?
3359 AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
3360 AR5K_SLOT_TIME);
3361 /* Set ACK_CTS timeout */
3362 ath5k_hw_reg_write(ah, ah->ah_turbo ?
3363 AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
3364 AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
3365 /* Set Transmit Latency */
3366 ath5k_hw_reg_write(ah, ah->ah_turbo ?
3367 AR5K_INIT_TRANSMIT_LATENCY_TURBO :
3368 AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
3369 /* Set IFS0 */
3370 if (ah->ah_turbo)
3371 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
3372 (ah->ah_aifs + tq->tqi_aifs) *
3373 AR5K_INIT_SLOT_TIME_TURBO) <<
3374 AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
3375 AR5K_IFS0);
3376 else
3377 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
3378 (ah->ah_aifs + tq->tqi_aifs) *
3379 AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
3380 AR5K_INIT_SIFS, AR5K_IFS0);
3381
3382 /* Set IFS1 */
3383 ath5k_hw_reg_write(ah, ah->ah_turbo ?
3384 AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
3385 AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
3386 /* Set AR5K_PHY_SETTLING */
3387 ath5k_hw_reg_write(ah, ah->ah_turbo ?
3388 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
3389 | 0x38 :
3390 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
3391 | 0x1C,
3392 AR5K_PHY_SETTLING);
3393 /* Set Frame Control Register */
3394 ath5k_hw_reg_write(ah, ah->ah_turbo ?
3395 (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
3396 AR5K_PHY_TURBO_SHORT | 0x2020) :
3397 (AR5K_PHY_FRAME_CTL_INI | 0x1020),
3398 AR5K_PHY_FRAME_CTL_5210);
3399 }
3400
3401 /*
3402 * Calculate cwmin/max by channel mode
3403 */
3404 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
3405 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
3406 ah->ah_aifs = AR5K_TUNE_AIFS;
3407 /*XR is only supported on 5212*/
3408 if (IS_CHAN_XR(ah->ah_current_channel) &&
3409 ah->ah_version == AR5K_AR5212) {
3410 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
3411 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
3412 ah->ah_aifs = AR5K_TUNE_AIFS_XR;
3413 /*B mode is not supported on 5210*/
3414 } else if (IS_CHAN_B(ah->ah_current_channel) &&
3415 ah->ah_version != AR5K_AR5210) {
3416 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
3417 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
3418 ah->ah_aifs = AR5K_TUNE_AIFS_11B;
3419 }
3420
3421 cw_min = 1;
3422 while (cw_min < ah->ah_cw_min)
3423 cw_min = (cw_min << 1) | 1;
3424
3425 cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
3426 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
3427 cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
3428 ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
3429
3430 /*
3431 * Calculate and set retry limits
3432 */
3433 if (ah->ah_software_retry) {
3434 /* XXX Need to test this */
3435 retry_lg = ah->ah_limit_tx_retries;
3436 retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
3437 AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
3438 } else {
3439 retry_lg = AR5K_INIT_LG_RETRY;
3440 retry_sh = AR5K_INIT_SH_RETRY;
3441 }
3442
3443 /*No QCU/DCU [5210]*/
3444 if (ah->ah_version == AR5K_AR5210) {
3445 ath5k_hw_reg_write(ah,
3446 (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
3447 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3448 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
3449 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3450 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
3451 | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
3452 | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
3453 AR5K_NODCU_RETRY_LMT);
3454 } else {
3455 /*QCU/DCU [5211+]*/
3456 ath5k_hw_reg_write(ah,
3457 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3458 AR5K_DCU_RETRY_LMT_SLG_RETRY) |
3459 AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3460 AR5K_DCU_RETRY_LMT_SSH_RETRY) |
3461 AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
3462 AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
3463 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
3464
3465 /*===Rest is also for QCU/DCU only [5211+]===*/
3466
3467 /*
3468 * Set initial content window (cw_min/cw_max)
3469 * and arbitrated interframe space (aifs)...
3470 */
3471 ath5k_hw_reg_write(ah,
3472 AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
3473 AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
3474 AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
3475 AR5K_DCU_LCL_IFS_AIFS),
3476 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
3477
3478 /*
3479 * Set misc registers
3480 */
3481 ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
3482 AR5K_QUEUE_MISC(queue));
3483
3484 if (tq->tqi_cbr_period) {
3485 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
3486 AR5K_QCU_CBRCFG_INTVAL) |
3487 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
3488 AR5K_QCU_CBRCFG_ORN_THRES),
3489 AR5K_QUEUE_CBRCFG(queue));
3490 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3491 AR5K_QCU_MISC_FRSHED_CBR);
3492 if (tq->tqi_cbr_overflow_limit)
3493 AR5K_REG_ENABLE_BITS(ah,
3494 AR5K_QUEUE_MISC(queue),
3495 AR5K_QCU_MISC_CBR_THRES_ENABLE);
3496 }
3497
3498 if (tq->tqi_ready_time)
3499 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
3500 AR5K_QCU_RDYTIMECFG_INTVAL) |
3501 AR5K_QCU_RDYTIMECFG_ENABLE,
3502 AR5K_QUEUE_RDYTIMECFG(queue));
3503
3504 if (tq->tqi_burst_time) {
3505 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
3506 AR5K_DCU_CHAN_TIME_DUR) |
3507 AR5K_DCU_CHAN_TIME_ENABLE,
3508 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
3509
3510 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
3511 AR5K_REG_ENABLE_BITS(ah,
3512 AR5K_QUEUE_MISC(queue),
3513 AR5K_QCU_MISC_RDY_VEOL_POLICY);
3514 }
3515
3516 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
3517 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
3518 AR5K_QUEUE_DFS_MISC(queue));
3519
3520 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
3521 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
3522 AR5K_QUEUE_DFS_MISC(queue));
3523
3524 /*
3525 * Set registers by queue type
3526 */
3527 switch (tq->tqi_type) {
3528 case AR5K_TX_QUEUE_BEACON:
3529 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3530 AR5K_QCU_MISC_FRSHED_DBA_GT |
3531 AR5K_QCU_MISC_CBREXP_BCN |
3532 AR5K_QCU_MISC_BCN_ENABLE);
3533
3534 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3535 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3536 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
3537 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
3538 AR5K_DCU_MISC_BCN_ENABLE);
3539
3540 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
3541 (AR5K_TUNE_SW_BEACON_RESP -
3542 AR5K_TUNE_DMA_BEACON_RESP) -
3543 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
3544 AR5K_QCU_RDYTIMECFG_ENABLE,
3545 AR5K_QUEUE_RDYTIMECFG(queue));
3546 break;
3547
3548 case AR5K_TX_QUEUE_CAB:
3549 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3550 AR5K_QCU_MISC_FRSHED_DBA_GT |
3551 AR5K_QCU_MISC_CBREXP |
3552 AR5K_QCU_MISC_CBREXP_BCN);
3553
3554 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3555 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3556 AR5K_DCU_MISC_ARBLOCK_CTL_S));
3557 break;
3558
3559 case AR5K_TX_QUEUE_UAPSD:
3560 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3561 AR5K_QCU_MISC_CBREXP);
3562 break;
3563
3564 case AR5K_TX_QUEUE_DATA:
3565 default:
3566 break;
3567 }
3568
3569 /*
3570 * Enable interrupts for this tx queue
3571 * in the secondary interrupt mask registers
3572 */
3573 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
3574 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
3575
3576 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
3577 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
3578
3579 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
3580 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
3581
3582 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
3583 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
3584
3585 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
3586 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
3587
3588
3589 /* Update secondary interrupt mask registers */
3590 ah->ah_txq_imr_txok &= ah->ah_txq_status;
3591 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
3592 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
3593 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
3594 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
3595
3596 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
3597 AR5K_SIMR0_QCU_TXOK) |
3598 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
3599 AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
3600 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
3601 AR5K_SIMR1_QCU_TXERR) |
3602 AR5K_REG_SM(ah->ah_txq_imr_txeol,
3603 AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
3604 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn,
3605 AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2);
3606 }
3607
3608 return 0;
3609}
3610
3611/*
3612 * Get number of pending frames
3613 * for a specific queue [5211+]
3614 */
3615u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) {
3616 ATH5K_TRACE(ah->ah_sc);
3617 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3618
3619 /* Return if queue is declared inactive */
3620 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3621 return false;
3622
3623 /* XXX: How about AR5K_CFG_TXCNT ? */
3624 if (ah->ah_version == AR5K_AR5210)
3625 return false;
3626
3627 return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
3628}
3629
3630/*
3631 * Set slot time
3632 */
3633int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
3634{
3635 ATH5K_TRACE(ah->ah_sc);
3636 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
3637 return -EINVAL;
3638
3639 if (ah->ah_version == AR5K_AR5210)
3640 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
3641 ah->ah_turbo), AR5K_SLOT_TIME);
3642 else
3643 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
3644
3645 return 0;
3646}
3647
3648/*
3649 * Get slot time
3650 */
3651unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
3652{
3653 ATH5K_TRACE(ah->ah_sc);
3654 if (ah->ah_version == AR5K_AR5210)
3655 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
3656 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
3657 else
3658 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
3659}
3660
3661
3662/******************************\
3663 Hardware Descriptor Functions
3664\******************************/
3665
3666/*
3667 * TX Descriptor
3668 */
3669
3670/*
3671 * Initialize the 2-word tx descriptor on 5210/5211
3672 */
3673static int
3674ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3675 unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
3676 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
3677 unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
3678 unsigned int rtscts_rate, unsigned int rtscts_duration)
3679{
3680 u32 frame_type;
3681 struct ath5k_hw_2w_tx_ctl *tx_ctl;
3682 unsigned int frame_len;
3683
3684 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
3685
3686 /*
3687 * Validate input
3688 * - Zero retries don't make sense.
3689 * - A zero rate will put the HW into a mode where it continously sends
3690 * noise on the channel, so it is important to avoid this.
3691 */
3692 if (unlikely(tx_tries0 == 0)) {
3693 ATH5K_ERR(ah->ah_sc, "zero retries\n");
3694 WARN_ON(1);
3695 return -EINVAL;
3696 }
3697 if (unlikely(tx_rate0 == 0)) {
3698 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3699 WARN_ON(1);
3700 return -EINVAL;
3701 }
3702
3703 /* Clear descriptor */
3704 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
3705
3706 /* Setup control descriptor */
3707
3708 /* Verify and set frame length */
3709
3710 /* remove padding we might have added before */
3711 frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
3712
3713 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
3714 return -EINVAL;
3715
3716 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
3717
3718 /* Verify and set buffer length */
3719
3720 /* NB: beacon's BufLen must be a multiple of 4 bytes */
3721 if(type == AR5K_PKT_TYPE_BEACON)
3722 pkt_len = roundup(pkt_len, 4);
3723
3724 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
3725 return -EINVAL;
3726
3727 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
3728
3729 /*
3730 * Verify and set header length
3731 * XXX: I only found that on 5210 code, does it work on 5211 ?
3732 */
3733 if (ah->ah_version == AR5K_AR5210) {
3734 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
3735 return -EINVAL;
3736 tx_ctl->tx_control_0 |=
3737 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
3738 }
3739
3740 /*Diferences between 5210-5211*/
3741 if (ah->ah_version == AR5K_AR5210) {
3742 switch (type) {
3743 case AR5K_PKT_TYPE_BEACON:
3744 case AR5K_PKT_TYPE_PROBE_RESP:
3745 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
3746 case AR5K_PKT_TYPE_PIFS:
3747 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
3748 default:
3749 frame_type = type /*<< 2 ?*/;
3750 }
3751
3752 tx_ctl->tx_control_0 |=
3753 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
3754 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3755 } else {
3756 tx_ctl->tx_control_0 |=
3757 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
3758 AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
3759 tx_ctl->tx_control_1 |=
3760 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
3761 }
3762#define _TX_FLAGS(_c, _flag) \
3763 if (flags & AR5K_TXDESC_##_flag) \
3764 tx_ctl->tx_control_##_c |= \
3765 AR5K_2W_TX_DESC_CTL##_c##_##_flag
3766
3767 _TX_FLAGS(0, CLRDMASK);
3768 _TX_FLAGS(0, VEOL);
3769 _TX_FLAGS(0, INTREQ);
3770 _TX_FLAGS(0, RTSENA);
3771 _TX_FLAGS(1, NOACK);
3772
3773#undef _TX_FLAGS
3774
3775 /*
3776 * WEP crap
3777 */
3778 if (key_index != AR5K_TXKEYIX_INVALID) {
3779 tx_ctl->tx_control_0 |=
3780 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
3781 tx_ctl->tx_control_1 |=
3782 AR5K_REG_SM(key_index,
3783 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3784 }
3785
3786 /*
3787 * RTS/CTS Duration [5210 ?]
3788 */
3789 if ((ah->ah_version == AR5K_AR5210) &&
3790 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
3791 tx_ctl->tx_control_1 |= rtscts_duration &
3792 AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
3793
3794 return 0;
3795}
3796
3797/*
3798 * Initialize the 4-word tx descriptor on 5212
3799 */
3800static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3801 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
3802 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
3803 unsigned int tx_tries0, unsigned int key_index,
3804 unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate,
3805 unsigned int rtscts_duration)
3806{
3807 struct ath5k_hw_4w_tx_ctl *tx_ctl;
3808 unsigned int frame_len;
3809
3810 ATH5K_TRACE(ah->ah_sc);
3811 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
3812
3813 /*
3814 * Validate input
3815 * - Zero retries don't make sense.
3816 * - A zero rate will put the HW into a mode where it continously sends
3817 * noise on the channel, so it is important to avoid this.
3818 */
3819 if (unlikely(tx_tries0 == 0)) {
3820 ATH5K_ERR(ah->ah_sc, "zero retries\n");
3821 WARN_ON(1);
3822 return -EINVAL;
3823 }
3824 if (unlikely(tx_rate0 == 0)) {
3825 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3826 WARN_ON(1);
3827 return -EINVAL;
3828 }
3829
3830 /* Clear descriptor */
3831 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
3832
3833 /* Setup control descriptor */
3834
3835 /* Verify and set frame length */
3836
3837 /* remove padding we might have added before */
3838 frame_len = pkt_len - (hdr_len & 3) + FCS_LEN;
3839
3840 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
3841 return -EINVAL;
3842
3843 tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
3844
3845 /* Verify and set buffer length */
3846
3847 /* NB: beacon's BufLen must be a multiple of 4 bytes */
3848 if(type == AR5K_PKT_TYPE_BEACON)
3849 pkt_len = roundup(pkt_len, 4);
3850
3851 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
3852 return -EINVAL;
3853
3854 tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
3855
3856 tx_ctl->tx_control_0 |=
3857 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
3858 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
3859 tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
3860 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
3861 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
3862 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
3863 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
3864
3865#define _TX_FLAGS(_c, _flag) \
3866 if (flags & AR5K_TXDESC_##_flag) \
3867 tx_ctl->tx_control_##_c |= \
3868 AR5K_4W_TX_DESC_CTL##_c##_##_flag
3869
3870 _TX_FLAGS(0, CLRDMASK);
3871 _TX_FLAGS(0, VEOL);
3872 _TX_FLAGS(0, INTREQ);
3873 _TX_FLAGS(0, RTSENA);
3874 _TX_FLAGS(0, CTSENA);
3875 _TX_FLAGS(1, NOACK);
3876
3877#undef _TX_FLAGS
3878
3879 /*
3880 * WEP crap
3881 */
3882 if (key_index != AR5K_TXKEYIX_INVALID) {
3883 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
3884 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
3885 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3886 }
3887
3888 /*
3889 * RTS/CTS
3890 */
3891 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
3892 if ((flags & AR5K_TXDESC_RTSENA) &&
3893 (flags & AR5K_TXDESC_CTSENA))
3894 return -EINVAL;
3895 tx_ctl->tx_control_2 |= rtscts_duration &
3896 AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
3897 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
3898 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
3899 }
3900
3901 return 0;
3902}
3903
3904/*
3905 * Initialize a 4-word multirate tx descriptor on 5212
3906 */
3907static int
3908ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3909 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
3910 unsigned int tx_rate3, u_int tx_tries3)
3911{
3912 struct ath5k_hw_4w_tx_ctl *tx_ctl;
3913
3914 /*
3915 * Rates can be 0 as long as the retry count is 0 too.
3916 * A zero rate and nonzero retry count will put the HW into a mode where
3917 * it continously sends noise on the channel, so it is important to
3918 * avoid this.
3919 */
3920 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
3921 (tx_rate2 == 0 && tx_tries2 != 0) ||
3922 (tx_rate3 == 0 && tx_tries3 != 0))) {
3923 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3924 WARN_ON(1);
3925 return -EINVAL;
3926 }
3927
3928 if (ah->ah_version == AR5K_AR5212) {
3929 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
3930
3931#define _XTX_TRIES(_n) \
3932 if (tx_tries##_n) { \
3933 tx_ctl->tx_control_2 |= \
3934 AR5K_REG_SM(tx_tries##_n, \
3935 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
3936 tx_ctl->tx_control_3 |= \
3937 AR5K_REG_SM(tx_rate##_n, \
3938 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
3939 }
3940
3941 _XTX_TRIES(1);
3942 _XTX_TRIES(2);
3943 _XTX_TRIES(3);
3944
3945#undef _XTX_TRIES
3946
3947 return 1;
3948 }
3949
3950 return 0;
3951}
3952
3953/*
3954 * Proccess the tx status descriptor on 5210/5211
3955 */
3956static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
3957 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
3958{
3959 struct ath5k_hw_2w_tx_ctl *tx_ctl;
3960 struct ath5k_hw_tx_status *tx_status;
3961
3962 ATH5K_TRACE(ah->ah_sc);
3963
3964 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
3965 tx_status = &desc->ud.ds_tx5210.tx_stat;
3966
3967 /* No frame has been send or error */
3968 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
3969 return -EINPROGRESS;
3970
3971 /*
3972 * Get descriptor status
3973 */
3974 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
3975 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
3976 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
3977 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
3978 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
3979 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
3980 /*TODO: ts->ts_virtcol + test*/
3981 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
3982 AR5K_DESC_TX_STATUS1_SEQ_NUM);
3983 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
3984 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
3985 ts->ts_antenna = 1;
3986 ts->ts_status = 0;
3987 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
3988 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3989
3990 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
3991 if (tx_status->tx_status_0 &
3992 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
3993 ts->ts_status |= AR5K_TXERR_XRETRY;
3994
3995 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
3996 ts->ts_status |= AR5K_TXERR_FIFO;
3997
3998 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
3999 ts->ts_status |= AR5K_TXERR_FILT;
4000 }
4001
4002 return 0;
4003}
4004
4005/*
4006 * Proccess a tx descriptor on 5212
4007 */
4008static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
4009 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
4010{
4011 struct ath5k_hw_4w_tx_ctl *tx_ctl;
4012 struct ath5k_hw_tx_status *tx_status;
4013
4014 ATH5K_TRACE(ah->ah_sc);
4015
4016 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
4017 tx_status = &desc->ud.ds_tx5212.tx_stat;
4018
4019 /* No frame has been send or error */
4020 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
4021 return -EINPROGRESS;
4022
4023 /*
4024 * Get descriptor status
4025 */
4026 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
4027 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
4028 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
4029 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
4030 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
4031 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
4032 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
4033 AR5K_DESC_TX_STATUS1_SEQ_NUM);
4034 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
4035 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
4036 ts->ts_antenna = (tx_status->tx_status_1 &
4037 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
4038 ts->ts_status = 0;
4039
4040 switch (AR5K_REG_MS(tx_status->tx_status_1,
4041 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
4042 case 0:
4043 ts->ts_rate = tx_ctl->tx_control_3 &
4044 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
4045 break;
4046 case 1:
4047 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
4048 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
4049 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
4050 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
4051 break;
4052 case 2:
4053 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
4054 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
4055 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
4056 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
4057 break;
4058 case 3:
4059 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
4060 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
4061 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
4062 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
4063 break;
4064 }
4065
4066 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
4067 if (tx_status->tx_status_0 &
4068 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
4069 ts->ts_status |= AR5K_TXERR_XRETRY;
4070
4071 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
4072 ts->ts_status |= AR5K_TXERR_FIFO;
4073
4074 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
4075 ts->ts_status |= AR5K_TXERR_FILT;
4076 }
4077
4078 return 0;
4079}
4080
4081/*
4082 * RX Descriptor
4083 */
4084
4085/*
4086 * Initialize an rx descriptor
4087 */
4088int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
4089 u32 size, unsigned int flags)
4090{
4091 struct ath5k_hw_rx_ctl *rx_ctl;
4092
4093 ATH5K_TRACE(ah->ah_sc);
4094 rx_ctl = &desc->ud.ds_rx.rx_ctl;
4095
4096 /*
4097 * Clear the descriptor
4098 * If we don't clean the status descriptor,
4099 * while scanning we get too many results,
4100 * most of them virtual, after some secs
4101 * of scanning system hangs. M.F.
4102 */
4103 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
4104
4105 /* Setup descriptor */
4106 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
4107 if (unlikely(rx_ctl->rx_control_1 != size))
4108 return -EINVAL;
4109
4110 if (flags & AR5K_RXDESC_INTREQ)
4111 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
4112
4113 return 0;
4114}
4115
4116/*
4117 * Proccess the rx status descriptor on 5210/5211
4118 */
4119static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
4120 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
4121{
4122 struct ath5k_hw_rx_status *rx_status;
4123
4124 rx_status = &desc->ud.ds_rx.u.rx_stat;
4125
4126 /* No frame received / not ready */
4127 if (unlikely((rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DONE)
4128 == 0))
4129 return -EINPROGRESS;
4130
4131 /*
4132 * Frame receive status
4133 */
4134 rs->rs_datalen = rx_status->rx_status_0 &
4135 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
4136 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
4137 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
4138 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
4139 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
4140 rs->rs_antenna = rx_status->rx_status_0 &
4141 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA;
4142 rs->rs_more = rx_status->rx_status_0 &
4143 AR5K_5210_RX_DESC_STATUS0_MORE;
4144 /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
4145 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
4146 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
4147 rs->rs_status = 0;
4148 rs->rs_phyerr = 0;
4149
4150 /*
4151 * Key table status
4152 */
4153 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
4154 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
4155 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
4156 else
4157 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
4158
4159 /*
4160 * Receive/descriptor errors
4161 */
4162 if ((rx_status->rx_status_1 &
4163 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4164 if (rx_status->rx_status_1 &
4165 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
4166 rs->rs_status |= AR5K_RXERR_CRC;
4167
4168 if (rx_status->rx_status_1 &
4169 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
4170 rs->rs_status |= AR5K_RXERR_FIFO;
4171
4172 if (rx_status->rx_status_1 &
4173 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
4174 rs->rs_status |= AR5K_RXERR_PHY;
4175 rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1,
4176 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
4177 }
4178
4179 if (rx_status->rx_status_1 &
4180 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
4181 rs->rs_status |= AR5K_RXERR_DECRYPT;
4182 }
4183
4184 return 0;
4185}
4186
4187/*
4188 * Proccess the rx status descriptor on 5212
4189 */
4190static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
4191 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
4192{
4193 struct ath5k_hw_rx_status *rx_status;
4194 struct ath5k_hw_rx_error *rx_err;
4195
4196 ATH5K_TRACE(ah->ah_sc);
4197 rx_status = &desc->ud.ds_rx.u.rx_stat;
4198
4199 /* Overlay on error */
4200 rx_err = &desc->ud.ds_rx.u.rx_err;
4201
4202 /* No frame received / not ready */
4203 if (unlikely((rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DONE)
4204 == 0))
4205 return -EINPROGRESS;
4206
4207 /*
4208 * Frame receive status
4209 */
4210 rs->rs_datalen = rx_status->rx_status_0 &
4211 AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
4212 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
4213 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
4214 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
4215 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
4216 rs->rs_antenna = rx_status->rx_status_0 &
4217 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA;
4218 rs->rs_more = rx_status->rx_status_0 &
4219 AR5K_5212_RX_DESC_STATUS0_MORE;
4220 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
4221 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
4222 rs->rs_status = 0;
4223 rs->rs_phyerr = 0;
4224
4225 /*
4226 * Key table status
4227 */
4228 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
4229 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
4230 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
4231 else
4232 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
4233
4234 /*
4235 * Receive/descriptor errors
4236 */
4237 if ((rx_status->rx_status_1 &
4238 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4239 if (rx_status->rx_status_1 &
4240 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
4241 rs->rs_status |= AR5K_RXERR_CRC;
4242
4243 if (rx_status->rx_status_1 &
4244 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
4245 rs->rs_status |= AR5K_RXERR_PHY;
4246 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
4247 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
4248 }
4249
4250 if (rx_status->rx_status_1 &
4251 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
4252 rs->rs_status |= AR5K_RXERR_DECRYPT;
4253
4254 if (rx_status->rx_status_1 &
4255 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
4256 rs->rs_status |= AR5K_RXERR_MIC;
4257 }
4258
4259 return 0;
4260}
4261
4262
4263/****************\
4264 GPIO Functions
4265\****************/
4266
4267/*
4268 * Set led state
4269 */
4270void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
4271{
4272 u32 led;
4273 /*5210 has different led mode handling*/
4274 u32 led_5210;
4275
4276 ATH5K_TRACE(ah->ah_sc);
4277
4278 /*Reset led status*/
4279 if (ah->ah_version != AR5K_AR5210)
4280 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
4281 AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED);
4282 else
4283 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
4284
4285 /*
4286 * Some blinking values, define at your wish
4287 */
4288 switch (state) {
4289 case AR5K_LED_SCAN:
4290 case AR5K_LED_AUTH:
4291 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
4292 led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
4293 break;
4294
4295 case AR5K_LED_INIT:
4296 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
4297 led_5210 = AR5K_PCICFG_LED_PEND;
4298 break;
4299
4300 case AR5K_LED_ASSOC:
4301 case AR5K_LED_RUN:
4302 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
4303 led_5210 = AR5K_PCICFG_LED_ASSOC;
4304 break;
4305
4306 default:
4307 led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
4308 led_5210 = AR5K_PCICFG_LED_PEND;
4309 break;
4310 }
4311
4312 /*Write new status to the register*/
4313 if (ah->ah_version != AR5K_AR5210)
4314 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
4315 else
4316 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
4317}
4318
4319/*
4320 * Set GPIO outputs
4321 */
4322int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
4323{
4324 ATH5K_TRACE(ah->ah_sc);
4325 if (gpio > AR5K_NUM_GPIO)
4326 return -EINVAL;
4327
4328 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4329 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
4330
4331 return 0;
4332}
4333
4334/*
4335 * Set GPIO inputs
4336 */
4337int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
4338{
4339 ATH5K_TRACE(ah->ah_sc);
4340 if (gpio > AR5K_NUM_GPIO)
4341 return -EINVAL;
4342
4343 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4344 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
4345
4346 return 0;
4347}
4348
4349/*
4350 * Get GPIO state
4351 */
4352u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
4353{
4354 ATH5K_TRACE(ah->ah_sc);
4355 if (gpio > AR5K_NUM_GPIO)
4356 return 0xffffffff;
4357
4358 /* GPIO input magic */
4359 return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
4360 0x1;
4361}
4362
4363/*
4364 * Set GPIO state
4365 */
4366int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
4367{
4368 u32 data;
4369 ATH5K_TRACE(ah->ah_sc);
4370
4371 if (gpio > AR5K_NUM_GPIO)
4372 return -EINVAL;
4373
4374 /* GPIO output magic */
4375 data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
4376
4377 data &= ~(1 << gpio);
4378 data |= (val & 1) << gpio;
4379
4380 ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
4381
4382 return 0;
4383}
4384
4385/*
4386 * Initialize the GPIO interrupt (RFKill switch)
4387 */
4388void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
4389 u32 interrupt_level)
4390{
4391 u32 data;
4392
4393 ATH5K_TRACE(ah->ah_sc);
4394 if (gpio > AR5K_NUM_GPIO)
4395 return;
4396
4397 /*
4398 * Set the GPIO interrupt
4399 */
4400 data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
4401 ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
4402 AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
4403 (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
4404
4405 ath5k_hw_reg_write(ah, interrupt_level ? data :
4406 (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
4407
4408 ah->ah_imr |= AR5K_IMR_GPIO;
4409
4410 /* Enable GPIO interrupts */
4411 AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
4412}
4413
4414
4415
4416
4417/****************\
4418 Misc functions
4419\****************/
4420
4421int ath5k_hw_get_capability(struct ath5k_hw *ah,
4422 enum ath5k_capability_type cap_type,
4423 u32 capability, u32 *result)
4424{
4425 ATH5K_TRACE(ah->ah_sc);
4426
4427 switch (cap_type) {
4428 case AR5K_CAP_NUM_TXQUEUES:
4429 if (result) {
4430 if (ah->ah_version == AR5K_AR5210)
4431 *result = AR5K_NUM_TX_QUEUES_NOQCU;
4432 else
4433 *result = AR5K_NUM_TX_QUEUES;
4434 goto yes;
4435 }
4436 case AR5K_CAP_VEOL:
4437 goto yes;
4438 case AR5K_CAP_COMPRESSION:
4439 if (ah->ah_version == AR5K_AR5212)
4440 goto yes;
4441 else
4442 goto no;
4443 case AR5K_CAP_BURST:
4444 goto yes;
4445 case AR5K_CAP_TPC:
4446 goto yes;
4447 case AR5K_CAP_BSSIDMASK:
4448 if (ah->ah_version == AR5K_AR5212)
4449 goto yes;
4450 else
4451 goto no;
4452 case AR5K_CAP_XR:
4453 if (ah->ah_version == AR5K_AR5212)
4454 goto yes;
4455 else
4456 goto no;
4457 default:
4458 goto no;
4459 }
4460
4461no:
4462 return -EINVAL;
4463yes:
4464 return 0;
4465}
4466
4467static int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
4468 u16 assoc_id)
4469{
4470 ATH5K_TRACE(ah->ah_sc);
4471
4472 if (ah->ah_version == AR5K_AR5210) {
4473 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
4474 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4475 return 0;
4476 }
4477
4478 return -EIO;
4479}
4480
4481static int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
4482{
4483 ATH5K_TRACE(ah->ah_sc);
4484
4485 if (ah->ah_version == AR5K_AR5210) {
4486 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
4487 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4488 return 0;
4489 }
4490
4491 return -EIO;
4492}
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
index 2806b21bf90b..ea2e1a20b499 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath5k/initvals.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * Initial register settings functions 2 * Initial register settings functions
3 * 3 *
4 * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> 4 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com> 5 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
6 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> 6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above 9 * purpose with or without fee is hereby granted, provided that the above
@@ -20,13 +20,9 @@
20 */ 20 */
21 21
22#include "ath5k.h" 22#include "ath5k.h"
23#include "base.h"
24#include "reg.h" 23#include "reg.h"
25 24#include "debug.h"
26/* 25#include "base.h"
27 * MAC/PHY REGISTERS
28 */
29
30 26
31/* 27/*
32 * Mode-independent initial register writes 28 * Mode-independent initial register writes
@@ -65,10 +61,10 @@ static const struct ath5k_ini ar5210_ini[] = {
65 { AR5K_TXCFG, AR5K_DMASIZE_128B }, 61 { AR5K_TXCFG, AR5K_DMASIZE_128B },
66 { AR5K_RXCFG, AR5K_DMASIZE_128B }, 62 { AR5K_RXCFG, AR5K_DMASIZE_128B },
67 { AR5K_CFG, AR5K_INIT_CFG }, 63 { AR5K_CFG, AR5K_INIT_CFG },
68 { AR5K_TOPS, AR5K_INIT_TOPS }, 64 { AR5K_TOPS, 8 },
69 { AR5K_RXNOFRM, AR5K_INIT_RXNOFRM }, 65 { AR5K_RXNOFRM, 8 },
70 { AR5K_RPGTO, AR5K_INIT_RPGTO }, 66 { AR5K_RPGTO, 0 },
71 { AR5K_TXNOFRM, AR5K_INIT_TXNOFRM }, 67 { AR5K_TXNOFRM, 0 },
72 { AR5K_SFR, 0 }, 68 { AR5K_SFR, 0 },
73 { AR5K_MIBC, 0 }, 69 { AR5K_MIBC, 0 },
74 { AR5K_MISC, 0 }, 70 { AR5K_MISC, 0 },
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c
new file mode 100644
index 000000000000..5a896d1e2a2b
--- /dev/null
+++ b/drivers/net/wireless/ath5k/pcu.c
@@ -0,0 +1,1002 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007-2008 Matthew W. S. Bell <mentor@madwifi.org>
5 * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
6 * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
7 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 */
22
23/*********************************\
24* Protocol Control Unit Functions *
25\*********************************/
26
27#include "ath5k.h"
28#include "reg.h"
29#include "debug.h"
30#include "base.h"
31
32/*******************\
33* Generic functions *
34\*******************/
35
36/**
37 * ath5k_hw_set_opmode - Set PCU operating mode
38 *
39 * @ah: The &struct ath5k_hw
40 *
41 * Initialize PCU for the various operating modes (AP/STA etc)
42 *
43 * NOTE: ah->ah_op_mode must be set before calling this.
44 */
45int ath5k_hw_set_opmode(struct ath5k_hw *ah)
46{
47 u32 pcu_reg, beacon_reg, low_id, high_id;
48
49 pcu_reg = 0;
50 beacon_reg = 0;
51
52 ATH5K_TRACE(ah->ah_sc);
53
54 switch (ah->ah_op_mode) {
55 case IEEE80211_IF_TYPE_IBSS:
56 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA |
57 (ah->ah_version == AR5K_AR5210 ?
58 AR5K_STA_ID1_NO_PSPOLL : 0);
59 beacon_reg |= AR5K_BCR_ADHOC;
60 break;
61
62 case IEEE80211_IF_TYPE_AP:
63 case IEEE80211_IF_TYPE_MESH_POINT:
64 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA |
65 (ah->ah_version == AR5K_AR5210 ?
66 AR5K_STA_ID1_NO_PSPOLL : 0);
67 beacon_reg |= AR5K_BCR_AP;
68 break;
69
70 case IEEE80211_IF_TYPE_STA:
71 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
72 (ah->ah_version == AR5K_AR5210 ?
73 AR5K_STA_ID1_PWR_SV : 0);
74 case IEEE80211_IF_TYPE_MNTR:
75 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
76 (ah->ah_version == AR5K_AR5210 ?
77 AR5K_STA_ID1_NO_PSPOLL : 0);
78 break;
79
80 default:
81 return -EINVAL;
82 }
83
84 /*
85 * Set PCU registers
86 */
87 low_id = AR5K_LOW_ID(ah->ah_sta_id);
88 high_id = AR5K_HIGH_ID(ah->ah_sta_id);
89 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
90 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
91
92 /*
93 * Set Beacon Control Register on 5210
94 */
95 if (ah->ah_version == AR5K_AR5210)
96 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
97
98 return 0;
99}
100
101/**
102 * ath5k_hw_update - Update mib counters (mac layer statistics)
103 *
104 * @ah: The &struct ath5k_hw
105 * @stats: The &struct ieee80211_low_level_stats we use to track
106 * statistics on the driver
107 *
108 * Reads MIB counters from PCU and updates sw statistics. Must be
109 * called after a MIB interrupt.
110 */
111void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
112 struct ieee80211_low_level_stats *stats)
113{
114 ATH5K_TRACE(ah->ah_sc);
115
116 /* Read-And-Clear */
117 stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
118 stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
119 stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
120 stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
121
122 /* XXX: Should we use this to track beacon count ?
123 * -we read it anyway to clear the register */
124 ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
125
126 /* Reset profile count registers on 5212*/
127 if (ah->ah_version == AR5K_AR5212) {
128 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
129 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
130 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
131 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
132 }
133}
134
135/**
136 * ath5k_hw_set_ack_bitrate - set bitrate for ACKs
137 *
138 * @ah: The &struct ath5k_hw
139 * @high: Flag to determine if we want to use high transmition rate
140 * for ACKs or not
141 *
142 * If high flag is set, we tell hw to use a set of control rates based on
143 * the current transmition rate (check out control_rates array inside reset.c).
144 * If not hw just uses the lowest rate available for the current modulation
145 * scheme being used (1Mbit for CCK and 6Mbits for OFDM).
146 */
147void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
148{
149 if (ah->ah_version != AR5K_AR5212)
150 return;
151 else {
152 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
153 if (high)
154 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
155 else
156 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
157 }
158}
159
160
161/******************\
162* ACK/CTS Timeouts *
163\******************/
164
165/**
166 * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
167 *
168 * @ah: The &struct ath5k_hw
169 */
170unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
171{
172 ATH5K_TRACE(ah->ah_sc);
173
174 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
175 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
176}
177
178/**
179 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
180 *
181 * @ah: The &struct ath5k_hw
182 * @timeout: Timeout in usec
183 */
184int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
185{
186 ATH5K_TRACE(ah->ah_sc);
187 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
188 ah->ah_turbo) <= timeout)
189 return -EINVAL;
190
191 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
192 ath5k_hw_htoclock(timeout, ah->ah_turbo));
193
194 return 0;
195}
196
197/**
198 * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
199 *
200 * @ah: The &struct ath5k_hw
201 */
202unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
203{
204 ATH5K_TRACE(ah->ah_sc);
205 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
206 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
207}
208
209/**
210 * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
211 *
212 * @ah: The &struct ath5k_hw
213 * @timeout: Timeout in usec
214 */
215int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
216{
217 ATH5K_TRACE(ah->ah_sc);
218 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
219 ah->ah_turbo) <= timeout)
220 return -EINVAL;
221
222 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
223 ath5k_hw_htoclock(timeout, ah->ah_turbo));
224
225 return 0;
226}
227
228
229/****************\
230* BSSID handling *
231\****************/
232
233/**
234 * ath5k_hw_get_lladdr - Get station id
235 *
236 * @ah: The &struct ath5k_hw
237 * @mac: The card's mac address
238 *
239 * Initialize ah->ah_sta_id using the mac address provided
240 * (just a memcpy).
241 *
242 * TODO: Remove it once we merge ath5k_softc and ath5k_hw
243 */
244void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
245{
246 ATH5K_TRACE(ah->ah_sc);
247 memcpy(mac, ah->ah_sta_id, ETH_ALEN);
248}
249
250/**
251 * ath5k_hw_set_lladdr - Set station id
252 *
253 * @ah: The &struct ath5k_hw
254 * @mac: The card's mac address
255 *
256 * Set station id on hw using the provided mac address
257 */
258int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
259{
260 u32 low_id, high_id;
261
262 ATH5K_TRACE(ah->ah_sc);
263 /* Set new station ID */
264 memcpy(ah->ah_sta_id, mac, ETH_ALEN);
265
266 low_id = AR5K_LOW_ID(mac);
267 high_id = AR5K_HIGH_ID(mac);
268
269 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
270 ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1);
271
272 return 0;
273}
274
275/**
276 * ath5k_hw_set_associd - Set BSSID for association
277 *
278 * @ah: The &struct ath5k_hw
279 * @bssid: BSSID
280 * @assoc_id: Assoc id
281 *
282 * Sets the BSSID which trigers the "SME Join" operation
283 */
284void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
285{
286 u32 low_id, high_id;
287 u16 tim_offset = 0;
288
289 /*
290 * Set simple BSSID mask on 5212
291 */
292 if (ah->ah_version == AR5K_AR5212) {
293 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0);
294 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1);
295 }
296
297 /*
298 * Set BSSID which triggers the "SME Join" operation
299 */
300 low_id = AR5K_LOW_ID(bssid);
301 high_id = AR5K_HIGH_ID(bssid);
302 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
303 ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
304 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
305
306 if (assoc_id == 0) {
307 ath5k_hw_disable_pspoll(ah);
308 return;
309 }
310
311 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
312 tim_offset ? tim_offset + 4 : 0);
313
314 ath5k_hw_enable_pspoll(ah, NULL, 0);
315}
316
317/**
318 * ath5k_hw_set_bssid_mask - filter out bssids we listen
319 *
320 * @ah: the &struct ath5k_hw
321 * @mask: the bssid_mask, a u8 array of size ETH_ALEN
322 *
323 * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
324 * which bits of the interface's MAC address should be looked at when trying
325 * to decide which packets to ACK. In station mode and AP mode with a single
326 * BSS every bit matters since we lock to only one BSS. In AP mode with
327 * multiple BSSes (virtual interfaces) not every bit matters because hw must
328 * accept frames for all BSSes and so we tweak some bits of our mac address
329 * in order to have multiple BSSes.
330 *
331 * NOTE: This is a simple filter and does *not* filter out all
332 * relevant frames. Some frames that are not for us might get ACKed from us
333 * by PCU because they just match the mask.
334 *
335 * When handling multiple BSSes you can get the BSSID mask by computing the
336 * set of ~ ( MAC XOR BSSID ) for all bssids we handle.
337 *
338 * When you do this you are essentially computing the common bits of all your
339 * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
340 * the MAC address to obtain the relevant bits and compare the result with
341 * (frame's BSSID & mask) to see if they match.
342 */
343/*
344 * Simple example: on your card you have have two BSSes you have created with
345 * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
346 * There is another BSSID-03 but you are not part of it. For simplicity's sake,
347 * assuming only 4 bits for a mac address and for BSSIDs you can then have:
348 *
349 * \
350 * MAC: 0001 |
351 * BSSID-01: 0100 | --> Belongs to us
352 * BSSID-02: 1001 |
353 * /
354 * -------------------
355 * BSSID-03: 0110 | --> External
356 * -------------------
357 *
358 * Our bssid_mask would then be:
359 *
360 * On loop iteration for BSSID-01:
361 * ~(0001 ^ 0100) -> ~(0101)
362 * -> 1010
363 * bssid_mask = 1010
364 *
365 * On loop iteration for BSSID-02:
366 * bssid_mask &= ~(0001 ^ 1001)
367 * bssid_mask = (1010) & ~(0001 ^ 1001)
368 * bssid_mask = (1010) & ~(1001)
369 * bssid_mask = (1010) & (0110)
370 * bssid_mask = 0010
371 *
372 * A bssid_mask of 0010 means "only pay attention to the second least
373 * significant bit". This is because its the only bit common
374 * amongst the MAC and all BSSIDs we support. To findout what the real
375 * common bit is we can simply "&" the bssid_mask now with any BSSID we have
376 * or our MAC address (we assume the hardware uses the MAC address).
377 *
378 * Now, suppose there's an incoming frame for BSSID-03:
379 *
380 * IFRAME-01: 0110
381 *
382 * An easy eye-inspeciton of this already should tell you that this frame
383 * will not pass our check. This is beacuse the bssid_mask tells the
384 * hardware to only look at the second least significant bit and the
385 * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
386 * as 1, which does not match 0.
387 *
388 * So with IFRAME-01 we *assume* the hardware will do:
389 *
390 * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
391 * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
392 * --> allow = (0010) == 0000 ? 1 : 0;
393 * --> allow = 0
394 *
395 * Lets now test a frame that should work:
396 *
397 * IFRAME-02: 0001 (we should allow)
398 *
399 * allow = (0001 & 1010) == 1010
400 *
401 * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
402 * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
403 * --> allow = (0010) == (0010)
404 * --> allow = 1
405 *
406 * Other examples:
407 *
408 * IFRAME-03: 0100 --> allowed
409 * IFRAME-04: 1001 --> allowed
410 * IFRAME-05: 1101 --> allowed but its not for us!!!
411 *
412 */
413int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
414{
415 u32 low_id, high_id;
416 ATH5K_TRACE(ah->ah_sc);
417
418 if (ah->ah_version == AR5K_AR5212) {
419 low_id = AR5K_LOW_ID(mask);
420 high_id = AR5K_HIGH_ID(mask);
421
422 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
423 ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
424
425 return 0;
426 }
427
428 return -EIO;
429}
430
431
432/************\
433* RX Control *
434\************/
435
436/**
437 * ath5k_hw_start_rx_pcu - Start RX engine
438 *
439 * @ah: The &struct ath5k_hw
440 *
441 * Starts RX engine on PCU so that hw can process RXed frames
442 * (ACK etc).
443 *
444 * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
445 * TODO: Init ANI here
446 */
447void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
448{
449 ATH5K_TRACE(ah->ah_sc);
450 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
451}
452
453/**
454 * at5k_hw_stop_rx_pcu - Stop RX engine
455 *
456 * @ah: The &struct ath5k_hw
457 *
458 * Stops RX engine on PCU
459 *
460 * TODO: Detach ANI here
461 */
462void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
463{
464 ATH5K_TRACE(ah->ah_sc);
465 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
466}
467
468/*
469 * Set multicast filter
470 */
471void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
472{
473 ATH5K_TRACE(ah->ah_sc);
474 /* Set the multicat filter */
475 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
476 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
477}
478
479/*
480 * Set multicast filter by index
481 */
482int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
483{
484
485 ATH5K_TRACE(ah->ah_sc);
486 if (index >= 64)
487 return -EINVAL;
488 else if (index >= 32)
489 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
490 (1 << (index - 32)));
491 else
492 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
493
494 return 0;
495}
496
497/*
498 * Clear Multicast filter by index
499 */
500int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
501{
502
503 ATH5K_TRACE(ah->ah_sc);
504 if (index >= 64)
505 return -EINVAL;
506 else if (index >= 32)
507 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
508 (1 << (index - 32)));
509 else
510 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
511
512 return 0;
513}
514
515/**
516 * ath5k_hw_get_rx_filter - Get current rx filter
517 *
518 * @ah: The &struct ath5k_hw
519 *
520 * Returns the RX filter by reading rx filter and
521 * phy error filter registers. RX filter is used
522 * to set the allowed frame types that PCU will accept
523 * and pass to the driver. For a list of frame types
524 * check out reg.h.
525 */
526u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
527{
528 u32 data, filter = 0;
529
530 ATH5K_TRACE(ah->ah_sc);
531 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
532
533 /*Radar detection for 5212*/
534 if (ah->ah_version == AR5K_AR5212) {
535 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
536
537 if (data & AR5K_PHY_ERR_FIL_RADAR)
538 filter |= AR5K_RX_FILTER_RADARERR;
539 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
540 filter |= AR5K_RX_FILTER_PHYERR;
541 }
542
543 return filter;
544}
545
546/**
547 * ath5k_hw_set_rx_filter - Set rx filter
548 *
549 * @ah: The &struct ath5k_hw
550 * @filter: RX filter mask (see reg.h)
551 *
552 * Sets RX filter register and also handles PHY error filter
553 * register on 5212 and newer chips so that we have proper PHY
554 * error reporting.
555 */
556void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
557{
558 u32 data = 0;
559
560 ATH5K_TRACE(ah->ah_sc);
561
562 /* Set PHY error filter register on 5212*/
563 if (ah->ah_version == AR5K_AR5212) {
564 if (filter & AR5K_RX_FILTER_RADARERR)
565 data |= AR5K_PHY_ERR_FIL_RADAR;
566 if (filter & AR5K_RX_FILTER_PHYERR)
567 data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
568 }
569
570 /*
571 * The AR5210 uses promiscous mode to detect radar activity
572 */
573 if (ah->ah_version == AR5K_AR5210 &&
574 (filter & AR5K_RX_FILTER_RADARERR)) {
575 filter &= ~AR5K_RX_FILTER_RADARERR;
576 filter |= AR5K_RX_FILTER_PROM;
577 }
578
579 /*Zero length DMA*/
580 if (data)
581 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
582 else
583 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
584
585 /*Write RX Filter register*/
586 ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
587
588 /*Write PHY error filter register on 5212*/
589 if (ah->ah_version == AR5K_AR5212)
590 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
591
592}
593
594
595/****************\
596* Beacon control *
597\****************/
598
599/**
600 * ath5k_hw_get_tsf32 - Get a 32bit TSF
601 *
602 * @ah: The &struct ath5k_hw
603 *
604 * Returns lower 32 bits of current TSF
605 */
606u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
607{
608 ATH5K_TRACE(ah->ah_sc);
609 return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
610}
611
612/**
613 * ath5k_hw_get_tsf64 - Get the full 64bit TSF
614 *
615 * @ah: The &struct ath5k_hw
616 *
617 * Returns the current TSF
618 */
619u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
620{
621 u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
622 ATH5K_TRACE(ah->ah_sc);
623
624 return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
625}
626
627/**
628 * ath5k_hw_reset_tsf - Force a TSF reset
629 *
630 * @ah: The &struct ath5k_hw
631 *
632 * Forces a TSF reset on PCU
633 */
634void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
635{
636 ATH5K_TRACE(ah->ah_sc);
637 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF);
638}
639
640/*
641 * Initialize beacon timers
642 */
643void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
644{
645 u32 timer1, timer2, timer3;
646
647 ATH5K_TRACE(ah->ah_sc);
648 /*
649 * Set the additional timers by mode
650 */
651 switch (ah->ah_op_mode) {
652 case IEEE80211_IF_TYPE_STA:
653 if (ah->ah_version == AR5K_AR5210) {
654 timer1 = 0xffffffff;
655 timer2 = 0xffffffff;
656 } else {
657 timer1 = 0x0000ffff;
658 timer2 = 0x0007ffff;
659 }
660 break;
661
662 default:
663 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
664 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
665 }
666
667 timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
668
669 /*
670 * Set the beacon register and enable all timers.
671 * (next beacon, DMA beacon, software beacon, ATIM window time)
672 */
673 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
674 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
675 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
676 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
677
678 ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
679 AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE),
680 AR5K_BEACON);
681}
682
683#if 0
684/*
685 * Set beacon timers
686 */
687int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
688 const struct ath5k_beacon_state *state)
689{
690 u32 cfp_period, next_cfp, dtim, interval, next_beacon;
691
692 /*
693 * TODO: should be changed through *state
694 * review struct ath5k_beacon_state struct
695 *
696 * XXX: These are used for cfp period bellow, are they
697 * ok ? Is it O.K. for tsf here to be 0 or should we use
698 * get_tsf ?
699 */
700 u32 dtim_count = 0; /* XXX */
701 u32 cfp_count = 0; /* XXX */
702 u32 tsf = 0; /* XXX */
703
704 ATH5K_TRACE(ah->ah_sc);
705 /* Return on an invalid beacon state */
706 if (state->bs_interval < 1)
707 return -EINVAL;
708
709 interval = state->bs_interval;
710 dtim = state->bs_dtim_period;
711
712 /*
713 * PCF support?
714 */
715 if (state->bs_cfp_period > 0) {
716 /*
717 * Enable PCF mode and set the CFP
718 * (Contention Free Period) and timer registers
719 */
720 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
721 state->bs_interval;
722 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
723 state->bs_interval;
724
725 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
726 AR5K_STA_ID1_DEFAULT_ANTENNA |
727 AR5K_STA_ID1_PCF);
728 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
729 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
730 AR5K_CFP_DUR);
731 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
732 next_cfp)) << 3, AR5K_TIMER2);
733 } else {
734 /* Disable PCF mode */
735 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
736 AR5K_STA_ID1_DEFAULT_ANTENNA |
737 AR5K_STA_ID1_PCF);
738 }
739
740 /*
741 * Enable the beacon timer register
742 */
743 ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
744
745 /*
746 * Start the beacon timers
747 */
748 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &
749 ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
750 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
751 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
752 AR5K_BEACON_PERIOD), AR5K_BEACON);
753
754 /*
755 * Write new beacon miss threshold, if it appears to be valid
756 * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
757 * and return if its not in range. We can test this by reading value and
758 * setting value to a largest value and seeing which values register.
759 */
760
761 AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
762 state->bs_bmiss_threshold);
763
764 /*
765 * Set sleep control register
766 * XXX: Didn't find this in 5210 code but since this register
767 * exists also in ar5k's 5210 headers i leave it as common code.
768 */
769 AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
770 (state->bs_sleep_duration - 3) << 3);
771
772 /*
773 * Set enhanced sleep registers on 5212
774 */
775 if (ah->ah_version == AR5K_AR5212) {
776 if (state->bs_sleep_duration > state->bs_interval &&
777 roundup(state->bs_sleep_duration, interval) ==
778 state->bs_sleep_duration)
779 interval = state->bs_sleep_duration;
780
781 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
782 roundup(state->bs_sleep_duration, dtim) ==
783 state->bs_sleep_duration))
784 dtim = state->bs_sleep_duration;
785
786 if (interval > dtim)
787 return -EINVAL;
788
789 next_beacon = interval == dtim ? state->bs_next_dtim :
790 state->bs_next_beacon;
791
792 ath5k_hw_reg_write(ah,
793 AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
794 AR5K_SLEEP0_NEXT_DTIM) |
795 AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
796 AR5K_SLEEP0_ENH_SLEEP_EN |
797 AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
798
799 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
800 AR5K_SLEEP1_NEXT_TIM) |
801 AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
802
803 ath5k_hw_reg_write(ah,
804 AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
805 AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
806 }
807
808 return 0;
809}
810
811/*
812 * Reset beacon timers
813 */
814void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
815{
816 ATH5K_TRACE(ah->ah_sc);
817 /*
818 * Disable beacon timer
819 */
820 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
821
822 /*
823 * Disable some beacon register values
824 */
825 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
826 AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
827 ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
828}
829
830/*
831 * Wait for beacon queue to finish
832 */
833int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
834{
835 unsigned int i;
836 int ret;
837
838 ATH5K_TRACE(ah->ah_sc);
839
840 /* 5210 doesn't have QCU*/
841 if (ah->ah_version == AR5K_AR5210) {
842 /*
843 * Wait for beaconn queue to finish by checking
844 * Control Register and Beacon Status Register.
845 */
846 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
847 if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
848 ||
849 !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
850 break;
851 udelay(10);
852 }
853
854 /* Timeout... */
855 if (i <= 0) {
856 /*
857 * Re-schedule the beacon queue
858 */
859 ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
860 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
861 AR5K_BCR);
862
863 return -EIO;
864 }
865 ret = 0;
866 } else {
867 /*5211/5212*/
868 ret = ath5k_hw_register_timeout(ah,
869 AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
870 AR5K_QCU_STS_FRMPENDCNT, 0, false);
871
872 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
873 return -EIO;
874 }
875
876 return ret;
877}
878#endif
879
880
881/*********************\
882* Key table functions *
883\*********************/
884
885/*
886 * Reset a key entry on the table
887 */
888int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
889{
890 unsigned int i;
891
892 ATH5K_TRACE(ah->ah_sc);
893 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
894
895 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
896 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
897
898 /*
899 * Set NULL encryption on AR5212+
900 *
901 * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
902 * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
903 *
904 * Note2: Windows driver (ndiswrapper) sets this to
905 * 0x00000714 instead of 0x00000007
906 */
907 if (ah->ah_version > AR5K_AR5211)
908 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
909 AR5K_KEYTABLE_TYPE(entry));
910
911 return 0;
912}
913
914/*
915 * Check if a table entry is valid
916 */
917int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
918{
919 ATH5K_TRACE(ah->ah_sc);
920 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
921
922 /* Check the validation flag at the end of the entry */
923 return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
924 AR5K_KEYTABLE_VALID;
925}
926
927/*
928 * Set a key entry on the table
929 */
930int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
931 const struct ieee80211_key_conf *key, const u8 *mac)
932{
933 unsigned int i;
934 __le32 key_v[5] = {};
935 u32 keytype;
936
937 ATH5K_TRACE(ah->ah_sc);
938
939 /* key->keylen comes in from mac80211 in bytes */
940
941 if (key->keylen > AR5K_KEYTABLE_SIZE / 8)
942 return -EOPNOTSUPP;
943
944 switch (key->keylen) {
945 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */
946 case 40 / 8:
947 memcpy(&key_v[0], key->key, 5);
948 keytype = AR5K_KEYTABLE_TYPE_40;
949 break;
950
951 /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */
952 case 104 / 8:
953 memcpy(&key_v[0], &key->key[0], 6);
954 memcpy(&key_v[2], &key->key[6], 6);
955 memcpy(&key_v[4], &key->key[12], 1);
956 keytype = AR5K_KEYTABLE_TYPE_104;
957 break;
958 /* WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */
959 case 128 / 8:
960 memcpy(&key_v[0], &key->key[0], 6);
961 memcpy(&key_v[2], &key->key[6], 6);
962 memcpy(&key_v[4], &key->key[12], 4);
963 keytype = AR5K_KEYTABLE_TYPE_128;
964 break;
965
966 default:
967 return -EINVAL; /* shouldn't happen */
968 }
969
970 for (i = 0; i < ARRAY_SIZE(key_v); i++)
971 ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
972 AR5K_KEYTABLE_OFF(entry, i));
973
974 ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
975
976 return ath5k_hw_set_key_lladdr(ah, entry, mac);
977}
978
979int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
980{
981 u32 low_id, high_id;
982
983 ATH5K_TRACE(ah->ah_sc);
984 /* Invalid entry (key table overflow) */
985 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
986
987 /* MAC may be NULL if it's a broadcast key. In this case no need to
988 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
989 if (unlikely(mac == NULL)) {
990 low_id = 0xffffffff;
991 high_id = 0xffff | AR5K_KEYTABLE_VALID;
992 } else {
993 low_id = AR5K_LOW_ID(mac);
994 high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
995 }
996
997 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
998 ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
999
1000 return 0;
1001}
1002
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index fa0d47faf574..1ea8ed962d26 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * PHY functions 2 * PHY functions
3 * 3 *
4 * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> 4 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com> 5 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
6 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> 6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above 9 * purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +19,8 @@
19 * 19 *
20 */ 20 */
21 21
22#define _ATH5K_PHY
23
22#include <linux/delay.h> 24#include <linux/delay.h>
23 25
24#include "ath5k.h" 26#include "ath5k.h"
@@ -2501,3 +2503,5 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power)
2501 2503
2502 return ath5k_hw_txpower(ah, channel, power); 2504 return ath5k_hw_txpower(ah, channel, power);
2503} 2505}
2506
2507#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c
new file mode 100644
index 000000000000..2e20f7816ca7
--- /dev/null
+++ b/drivers/net/wireless/ath5k/qcu.c
@@ -0,0 +1,488 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 */
18
19/********************************************\
20Queue Control Unit, DFS Control Unit Functions
21\********************************************/
22
23#include "ath5k.h"
24#include "reg.h"
25#include "debug.h"
26#include "base.h"
27
28/*
29 * Get properties for a transmit queue
30 */
31int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
32 struct ath5k_txq_info *queue_info)
33{
34 ATH5K_TRACE(ah->ah_sc);
35 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
36 return 0;
37}
38
39/*
40 * Set properties for a transmit queue
41 */
42int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
43 const struct ath5k_txq_info *queue_info)
44{
45 ATH5K_TRACE(ah->ah_sc);
46 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
47
48 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
49 return -EIO;
50
51 memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
52
53 /*XXX: Is this supported on 5210 ?*/
54 if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
55 ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
56 (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
57 queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
58 ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
59
60 return 0;
61}
62
63/*
64 * Initialize a transmit queue
65 */
66int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
67 struct ath5k_txq_info *queue_info)
68{
69 unsigned int queue;
70 int ret;
71
72 ATH5K_TRACE(ah->ah_sc);
73
74 /*
75 * Get queue by type
76 */
77 /*5210 only has 2 queues*/
78 if (ah->ah_version == AR5K_AR5210) {
79 switch (queue_type) {
80 case AR5K_TX_QUEUE_DATA:
81 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
82 break;
83 case AR5K_TX_QUEUE_BEACON:
84 case AR5K_TX_QUEUE_CAB:
85 queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
86 break;
87 default:
88 return -EINVAL;
89 }
90 } else {
91 switch (queue_type) {
92 case AR5K_TX_QUEUE_DATA:
93 for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
94 ah->ah_txq[queue].tqi_type !=
95 AR5K_TX_QUEUE_INACTIVE; queue++) {
96
97 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
98 return -EINVAL;
99 }
100 break;
101 case AR5K_TX_QUEUE_UAPSD:
102 queue = AR5K_TX_QUEUE_ID_UAPSD;
103 break;
104 case AR5K_TX_QUEUE_BEACON:
105 queue = AR5K_TX_QUEUE_ID_BEACON;
106 break;
107 case AR5K_TX_QUEUE_CAB:
108 queue = AR5K_TX_QUEUE_ID_CAB;
109 break;
110 case AR5K_TX_QUEUE_XR_DATA:
111 if (ah->ah_version != AR5K_AR5212)
112 ATH5K_ERR(ah->ah_sc,
113 "XR data queues only supported in"
114 " 5212!\n");
115 queue = AR5K_TX_QUEUE_ID_XR_DATA;
116 break;
117 default:
118 return -EINVAL;
119 }
120 }
121
122 /*
123 * Setup internal queue structure
124 */
125 memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
126 ah->ah_txq[queue].tqi_type = queue_type;
127
128 if (queue_info != NULL) {
129 queue_info->tqi_type = queue_type;
130 ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
131 if (ret)
132 return ret;
133 }
134
135 /*
136 * We use ah_txq_status to hold a temp value for
137 * the Secondary interrupt mask registers on 5211+
138 * check out ath5k_hw_reset_tx_queue
139 */
140 AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
141
142 return queue;
143}
144
145/*
146 * Get number of pending frames
147 * for a specific queue [5211+]
148 */
149u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
150{
151 ATH5K_TRACE(ah->ah_sc);
152 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
153
154 /* Return if queue is declared inactive */
155 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
156 return false;
157
158 /* XXX: How about AR5K_CFG_TXCNT ? */
159 if (ah->ah_version == AR5K_AR5210)
160 return false;
161
162 return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
163}
164
165/*
166 * Set a transmit queue inactive
167 */
168void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
169{
170 ATH5K_TRACE(ah->ah_sc);
171 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
172 return;
173
174 /* This queue will be skipped in further operations */
175 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
176 /*For SIMR setup*/
177 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
178}
179
180/*
181 * Set DFS properties for a transmit queue on DCU
182 */
183int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
184{
185 u32 cw_min, cw_max, retry_lg, retry_sh;
186 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
187
188 ATH5K_TRACE(ah->ah_sc);
189 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
190
191 tq = &ah->ah_txq[queue];
192
193 if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
194 return 0;
195
196 if (ah->ah_version == AR5K_AR5210) {
197 /* Only handle data queues, others will be ignored */
198 if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
199 return 0;
200
201 /* Set Slot time */
202 ath5k_hw_reg_write(ah, ah->ah_turbo ?
203 AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
204 AR5K_SLOT_TIME);
205 /* Set ACK_CTS timeout */
206 ath5k_hw_reg_write(ah, ah->ah_turbo ?
207 AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
208 AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
209 /* Set Transmit Latency */
210 ath5k_hw_reg_write(ah, ah->ah_turbo ?
211 AR5K_INIT_TRANSMIT_LATENCY_TURBO :
212 AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
213
214 /* Set IFS0 */
215 if (ah->ah_turbo) {
216 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
217 (ah->ah_aifs + tq->tqi_aifs) *
218 AR5K_INIT_SLOT_TIME_TURBO) <<
219 AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
220 AR5K_IFS0);
221 } else {
222 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
223 (ah->ah_aifs + tq->tqi_aifs) *
224 AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
225 AR5K_INIT_SIFS, AR5K_IFS0);
226 }
227
228 /* Set IFS1 */
229 ath5k_hw_reg_write(ah, ah->ah_turbo ?
230 AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
231 AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
232 /* Set AR5K_PHY_SETTLING */
233 ath5k_hw_reg_write(ah, ah->ah_turbo ?
234 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
235 | 0x38 :
236 (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
237 | 0x1C,
238 AR5K_PHY_SETTLING);
239 /* Set Frame Control Register */
240 ath5k_hw_reg_write(ah, ah->ah_turbo ?
241 (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
242 AR5K_PHY_TURBO_SHORT | 0x2020) :
243 (AR5K_PHY_FRAME_CTL_INI | 0x1020),
244 AR5K_PHY_FRAME_CTL_5210);
245 }
246
247 /*
248 * Calculate cwmin/max by channel mode
249 */
250 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
251 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
252 ah->ah_aifs = AR5K_TUNE_AIFS;
253 /*XR is only supported on 5212*/
254 if (IS_CHAN_XR(ah->ah_current_channel) &&
255 ah->ah_version == AR5K_AR5212) {
256 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
257 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
258 ah->ah_aifs = AR5K_TUNE_AIFS_XR;
259 /*B mode is not supported on 5210*/
260 } else if (IS_CHAN_B(ah->ah_current_channel) &&
261 ah->ah_version != AR5K_AR5210) {
262 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
263 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
264 ah->ah_aifs = AR5K_TUNE_AIFS_11B;
265 }
266
267 cw_min = 1;
268 while (cw_min < ah->ah_cw_min)
269 cw_min = (cw_min << 1) | 1;
270
271 cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
272 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
273 cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
274 ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
275
276 /*
277 * Calculate and set retry limits
278 */
279 if (ah->ah_software_retry) {
280 /* XXX Need to test this */
281 retry_lg = ah->ah_limit_tx_retries;
282 retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
283 AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
284 } else {
285 retry_lg = AR5K_INIT_LG_RETRY;
286 retry_sh = AR5K_INIT_SH_RETRY;
287 }
288
289 /*No QCU/DCU [5210]*/
290 if (ah->ah_version == AR5K_AR5210) {
291 ath5k_hw_reg_write(ah,
292 (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
293 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
294 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
295 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
296 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
297 | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
298 | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
299 AR5K_NODCU_RETRY_LMT);
300 } else {
301 /*QCU/DCU [5211+]*/
302 ath5k_hw_reg_write(ah,
303 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
304 AR5K_DCU_RETRY_LMT_SLG_RETRY) |
305 AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
306 AR5K_DCU_RETRY_LMT_SSH_RETRY) |
307 AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
308 AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
309 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
310
311 /*===Rest is also for QCU/DCU only [5211+]===*/
312
313 /*
314 * Set initial content window (cw_min/cw_max)
315 * and arbitrated interframe space (aifs)...
316 */
317 ath5k_hw_reg_write(ah,
318 AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
319 AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
320 AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
321 AR5K_DCU_LCL_IFS_AIFS),
322 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
323
324 /*
325 * Set misc registers
326 */
327 ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
328 AR5K_QUEUE_MISC(queue));
329
330 if (tq->tqi_cbr_period) {
331 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
332 AR5K_QCU_CBRCFG_INTVAL) |
333 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
334 AR5K_QCU_CBRCFG_ORN_THRES),
335 AR5K_QUEUE_CBRCFG(queue));
336 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
337 AR5K_QCU_MISC_FRSHED_CBR);
338 if (tq->tqi_cbr_overflow_limit)
339 AR5K_REG_ENABLE_BITS(ah,
340 AR5K_QUEUE_MISC(queue),
341 AR5K_QCU_MISC_CBR_THRES_ENABLE);
342 }
343
344 if (tq->tqi_ready_time)
345 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
346 AR5K_QCU_RDYTIMECFG_INTVAL) |
347 AR5K_QCU_RDYTIMECFG_ENABLE,
348 AR5K_QUEUE_RDYTIMECFG(queue));
349
350 if (tq->tqi_burst_time) {
351 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
352 AR5K_DCU_CHAN_TIME_DUR) |
353 AR5K_DCU_CHAN_TIME_ENABLE,
354 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
355
356 if (tq->tqi_flags
357 & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
358 AR5K_REG_ENABLE_BITS(ah,
359 AR5K_QUEUE_MISC(queue),
360 AR5K_QCU_MISC_RDY_VEOL_POLICY);
361 }
362
363 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
364 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
365 AR5K_QUEUE_DFS_MISC(queue));
366
367 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
368 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
369 AR5K_QUEUE_DFS_MISC(queue));
370
371 /*
372 * Set registers by queue type
373 */
374 switch (tq->tqi_type) {
375 case AR5K_TX_QUEUE_BEACON:
376 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
377 AR5K_QCU_MISC_FRSHED_DBA_GT |
378 AR5K_QCU_MISC_CBREXP_BCN |
379 AR5K_QCU_MISC_BCN_ENABLE);
380
381 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
382 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
383 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
384 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
385 AR5K_DCU_MISC_BCN_ENABLE);
386
387 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
388 (AR5K_TUNE_SW_BEACON_RESP -
389 AR5K_TUNE_DMA_BEACON_RESP) -
390 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
391 AR5K_QCU_RDYTIMECFG_ENABLE,
392 AR5K_QUEUE_RDYTIMECFG(queue));
393 break;
394
395 case AR5K_TX_QUEUE_CAB:
396 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
397 AR5K_QCU_MISC_FRSHED_DBA_GT |
398 AR5K_QCU_MISC_CBREXP |
399 AR5K_QCU_MISC_CBREXP_BCN);
400
401 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
402 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
403 AR5K_DCU_MISC_ARBLOCK_CTL_S));
404 break;
405
406 case AR5K_TX_QUEUE_UAPSD:
407 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
408 AR5K_QCU_MISC_CBREXP);
409 break;
410
411 case AR5K_TX_QUEUE_DATA:
412 default:
413 break;
414 }
415
416 /*
417 * Enable interrupts for this tx queue
418 * in the secondary interrupt mask registers
419 */
420 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
421 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
422
423 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
424 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
425
426 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
427 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
428
429 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
430 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
431
432 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
433 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
434
435
436 /* Update secondary interrupt mask registers */
437 ah->ah_txq_imr_txok &= ah->ah_txq_status;
438 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
439 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
440 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
441 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
442
443 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
444 AR5K_SIMR0_QCU_TXOK) |
445 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
446 AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
447 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
448 AR5K_SIMR1_QCU_TXERR) |
449 AR5K_REG_SM(ah->ah_txq_imr_txeol,
450 AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
451 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn,
452 AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2);
453 }
454
455 return 0;
456}
457
458/*
459 * Get slot time from DCU
460 */
461unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
462{
463 ATH5K_TRACE(ah->ah_sc);
464 if (ah->ah_version == AR5K_AR5210)
465 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
466 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
467 else
468 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
469}
470
471/*
472 * Set slot time on DCU
473 */
474int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
475{
476 ATH5K_TRACE(ah->ah_sc);
477 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
478 return -EINVAL;
479
480 if (ah->ah_version == AR5K_AR5210)
481 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
482 ah->ah_turbo), AR5K_SLOT_TIME);
483 else
484 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
485
486 return 0;
487}
488
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index 7562bf173d3e..a98832364448 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2007 Nick Kossifidis <mickflemm@gmail.com> 2 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
3 * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> 3 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
4 * Copyright (c) 2007 Michael Taylor <mike.taylor@apprion.com> 4 * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com>
5 * 5 *
6 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -977,98 +977,6 @@
977#define AR5K_EEPROM_BASE 0x6000 977#define AR5K_EEPROM_BASE 0x6000
978 978
979/* 979/*
980 * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
981 */
982#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
983#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
984#define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
985#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
986#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
987
988#define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */
989#define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */
990#define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */
991#define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */
992#define AR5K_EEPROM_PROTECT_WR_32_63 0x0008
993#define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */
994#define AR5K_EEPROM_PROTECT_WR_64_127 0x0020
995#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */
996#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
997#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */
998#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
999#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */
1000#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
1001#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */
1002#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
1003#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */
1004#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
1005#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
1006#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
1007#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
1008#define AR5K_EEPROM_INFO_CKSUM 0xffff
1009#define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n))
1010
1011#define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */
1012#define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */
1013#define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */
1014#define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */
1015#define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
1016#define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */
1017#define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
1018#define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */
1019#define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */
1020#define AR5K_EEPROM_VERSION_4_3 0x4003
1021#define AR5K_EEPROM_VERSION_4_4 0x4004
1022#define AR5K_EEPROM_VERSION_4_5 0x4005
1023#define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */
1024#define AR5K_EEPROM_VERSION_4_7 0x4007
1025
1026#define AR5K_EEPROM_MODE_11A 0
1027#define AR5K_EEPROM_MODE_11B 1
1028#define AR5K_EEPROM_MODE_11G 2
1029
1030#define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */
1031#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
1032#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
1033#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
1034#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */
1035#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */
1036#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7)
1037#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz (?) */
1038#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
1039
1040#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
1041#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
1042#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
1043#define AR5K_EEPROM_RFKILL_POLARITY_S 1
1044
1045/* Newer EEPROMs are using a different offset */
1046#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
1047 (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
1048
1049#define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
1050#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((int8_t)(((_v) >> 8) & 0xff))
1051#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff))
1052
1053/* calibration settings */
1054#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
1055#define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
1056#define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
1057#define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */
1058
1059/* [3.1 - 3.3] */
1060#define AR5K_EEPROM_OBDB0_2GHZ 0x00ec
1061#define AR5K_EEPROM_OBDB1_2GHZ 0x00ed
1062
1063/* Misc values available since EEPROM 4.0 */
1064#define AR5K_EEPROM_MISC0 0x00c4
1065#define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff)
1066#define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3)
1067#define AR5K_EEPROM_MISC1 0x00c5
1068#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
1069#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1)
1070
1071/*
1072 * EEPROM data register 980 * EEPROM data register
1073 */ 981 */
1074#define AR5K_EEPROM_DATA_5211 0x6004 982#define AR5K_EEPROM_DATA_5211 0x6004
@@ -1950,13 +1858,13 @@
1950#define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */ 1858#define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */
1951 1859
1952/* 1860/*
1953 * Desired size register 1861 * Desired ADC/PGA size register
1954 * (for more infos read ANI patent) 1862 * (for more infos read ANI patent)
1955 */ 1863 */
1956#define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */ 1864#define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */
1957#define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* Mask for ADC desired size */ 1865#define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* Mask for ADC desired size */
1958#define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* Mask for PGA desired size */ 1866#define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* Mask for PGA desired size */
1959#define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Mask for Total desired size (?) */ 1867#define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Mask for Total desired size */
1960 1868
1961/* 1869/*
1962 * PHY signal register 1870 * PHY signal register
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
new file mode 100644
index 000000000000..d260fba0180f
--- /dev/null
+++ b/drivers/net/wireless/ath5k/reset.c
@@ -0,0 +1,925 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
5 * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *
20 */
21
22#define _ATH5K_RESET
23
24/*****************************\
25 Reset functions and helpers
26\*****************************/
27
28#include <linux/pci.h>
29#include "ath5k.h"
30#include "reg.h"
31#include "base.h"
32#include "debug.h"
33
34/**
35 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
36 *
37 * @ah: the &struct ath5k_hw
38 * @channel: the currently set channel upon reset
39 *
40 * Write the OFDM timings for the AR5212 upon reset. This is a helper for
41 * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
42 * depending on the bandwidth of the channel.
43 *
44 */
45static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
46 struct ieee80211_channel *channel)
47{
48 /* Get exponent and mantissa and set it */
49 u32 coef_scaled, coef_exp, coef_man,
50 ds_coef_exp, ds_coef_man, clock;
51
52 if (!(ah->ah_version == AR5K_AR5212) ||
53 !(channel->hw_value & CHANNEL_OFDM))
54 BUG();
55
56 /* Seems there are two PLLs, one for baseband sampling and one
57 * for tuning. Tuning basebands are 40 MHz or 80MHz when in
58 * turbo. */
59 clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
60 coef_scaled = ((5 * (clock << 24)) / 2) /
61 channel->center_freq;
62
63 for (coef_exp = 31; coef_exp > 0; coef_exp--)
64 if ((coef_scaled >> coef_exp) & 0x1)
65 break;
66
67 if (!coef_exp)
68 return -EINVAL;
69
70 coef_exp = 14 - (coef_exp - 24);
71 coef_man = coef_scaled +
72 (1 << (24 - coef_exp - 1));
73 ds_coef_man = coef_man >> (24 - coef_exp);
74 ds_coef_exp = coef_exp - 16;
75
76 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
77 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
78 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
79 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
80
81 return 0;
82}
83
84
85/*
86 * index into rates for control rates, we can set it up like this because
87 * this is only used for AR5212 and we know it supports G mode
88 */
89static int control_rates[] =
90 { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
91
92/**
93 * ath5k_hw_write_rate_duration - set rate duration during hw resets
94 *
95 * @ah: the &struct ath5k_hw
96 * @mode: one of enum ath5k_driver_mode
97 *
98 * Write the rate duration table upon hw reset. This is a helper for
99 * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for
100 * the hardware for the current mode for each rate. The rates which are capable
101 * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another
102 * register for the short preamble ACK timeout calculation.
103 */
104static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
105 unsigned int mode)
106{
107 struct ath5k_softc *sc = ah->ah_sc;
108 struct ieee80211_rate *rate;
109 unsigned int i;
110
111 /* Write rate duration table */
112 for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
113 u32 reg;
114 u16 tx_time;
115
116 rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
117
118 /* Set ACK timeout */
119 reg = AR5K_RATE_DUR(rate->hw_value);
120
121 /* An ACK frame consists of 10 bytes. If you add the FCS,
122 * which ieee80211_generic_frame_duration() adds,
123 * its 14 bytes. Note we use the control rate and not the
124 * actual rate for this rate. See mac80211 tx.c
125 * ieee80211_duration() for a brief description of
126 * what rate we should choose to TX ACKs. */
127 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
128 sc->vif, 10, rate));
129
130 ath5k_hw_reg_write(ah, tx_time, reg);
131
132 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
133 continue;
134
135 /*
136 * We're not distinguishing short preamble here,
137 * This is true, all we'll get is a longer value here
138 * which is not necessarilly bad. We could use
139 * export ieee80211_frame_duration() but that needs to be
140 * fixed first to be properly used by mac802111 drivers:
141 *
142 * - remove erp stuff and let the routine figure ofdm
143 * erp rates
144 * - remove passing argument ieee80211_local as
145 * drivers don't have access to it
146 * - move drivers using ieee80211_generic_frame_duration()
147 * to this
148 */
149 ath5k_hw_reg_write(ah, tx_time,
150 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
151 }
152}
153
154/*
155 * Reset chipset
156 */
157static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
158{
159 int ret;
160 u32 mask = val ? val : ~0U;
161
162 ATH5K_TRACE(ah->ah_sc);
163
164 /* Read-and-clear RX Descriptor Pointer*/
165 ath5k_hw_reg_read(ah, AR5K_RXDP);
166
167 /*
168 * Reset the device and wait until success
169 */
170 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
171
172 /* Wait at least 128 PCI clocks */
173 udelay(15);
174
175 if (ah->ah_version == AR5K_AR5210) {
176 val &= AR5K_RESET_CTL_CHIP;
177 mask &= AR5K_RESET_CTL_CHIP;
178 } else {
179 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
180 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
181 }
182
183 ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
184
185 /*
186 * Reset configuration register (for hw byte-swap). Note that this
187 * is only set for big endian. We do the necessary magic in
188 * AR5K_INIT_CFG.
189 */
190 if ((val & AR5K_RESET_CTL_PCU) == 0)
191 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
192
193 return ret;
194}
195
196/*
197 * Sleep control
198 */
199int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
200 bool set_chip, u16 sleep_duration)
201{
202 unsigned int i;
203 u32 staid, data;
204
205 ATH5K_TRACE(ah->ah_sc);
206 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
207
208 switch (mode) {
209 case AR5K_PM_AUTO:
210 staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
211 /* fallthrough */
212 case AR5K_PM_NETWORK_SLEEP:
213 if (set_chip)
214 ath5k_hw_reg_write(ah,
215 AR5K_SLEEP_CTL_SLE_ALLOW |
216 sleep_duration,
217 AR5K_SLEEP_CTL);
218
219 staid |= AR5K_STA_ID1_PWR_SV;
220 break;
221
222 case AR5K_PM_FULL_SLEEP:
223 if (set_chip)
224 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
225 AR5K_SLEEP_CTL);
226
227 staid |= AR5K_STA_ID1_PWR_SV;
228 break;
229
230 case AR5K_PM_AWAKE:
231
232 staid &= ~AR5K_STA_ID1_PWR_SV;
233
234 if (!set_chip)
235 goto commit;
236
237 /* Preserve sleep duration */
238 data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
239 if (data & 0xffc00000)
240 data = 0;
241 else
242 data = data & 0xfffcffff;
243
244 ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
245 udelay(15);
246
247 for (i = 50; i > 0; i--) {
248 /* Check if the chip did wake up */
249 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
250 AR5K_PCICFG_SPWR_DN) == 0)
251 break;
252
253 /* Wait a bit and retry */
254 udelay(200);
255 ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
256 }
257
258 /* Fail if the chip didn't wake up */
259 if (i <= 0)
260 return -EIO;
261
262 break;
263
264 default:
265 return -EINVAL;
266 }
267
268commit:
269 ah->ah_power_mode = mode;
270 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
271
272 return 0;
273}
274
275/*
276 * Bring up MAC + PHY Chips
277 */
278int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
279{
280 struct pci_dev *pdev = ah->ah_sc->pdev;
281 u32 turbo, mode, clock, bus_flags;
282 int ret;
283
284 turbo = 0;
285 mode = 0;
286 clock = 0;
287
288 ATH5K_TRACE(ah->ah_sc);
289
290 /* Wakeup the device */
291 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
292 if (ret) {
293 ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
294 return ret;
295 }
296
297 if (ah->ah_version != AR5K_AR5210) {
298 /*
299 * Get channel mode flags
300 */
301
302 if (ah->ah_radio >= AR5K_RF5112) {
303 mode = AR5K_PHY_MODE_RAD_RF5112;
304 clock = AR5K_PHY_PLL_RF5112;
305 } else {
306 mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/
307 clock = AR5K_PHY_PLL_RF5111; /*Zero*/
308 }
309
310 if (flags & CHANNEL_2GHZ) {
311 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
312 clock |= AR5K_PHY_PLL_44MHZ;
313
314 if (flags & CHANNEL_CCK) {
315 mode |= AR5K_PHY_MODE_MOD_CCK;
316 } else if (flags & CHANNEL_OFDM) {
317 /* XXX Dynamic OFDM/CCK is not supported by the
318 * AR5211 so we set MOD_OFDM for plain g (no
319 * CCK headers) operation. We need to test
320 * this, 5211 might support ofdm-only g after
321 * all, there are also initial register values
322 * in the code for g mode (see initvals.c). */
323 if (ah->ah_version == AR5K_AR5211)
324 mode |= AR5K_PHY_MODE_MOD_OFDM;
325 else
326 mode |= AR5K_PHY_MODE_MOD_DYN;
327 } else {
328 ATH5K_ERR(ah->ah_sc,
329 "invalid radio modulation mode\n");
330 return -EINVAL;
331 }
332 } else if (flags & CHANNEL_5GHZ) {
333 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
334 clock |= AR5K_PHY_PLL_40MHZ;
335
336 if (flags & CHANNEL_OFDM)
337 mode |= AR5K_PHY_MODE_MOD_OFDM;
338 else {
339 ATH5K_ERR(ah->ah_sc,
340 "invalid radio modulation mode\n");
341 return -EINVAL;
342 }
343 } else {
344 ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
345 return -EINVAL;
346 }
347
348 if (flags & CHANNEL_TURBO)
349 turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
350 } else { /* Reset the device */
351
352 /* ...enable Atheros turbo mode if requested */
353 if (flags & CHANNEL_TURBO)
354 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
355 AR5K_PHY_TURBO);
356 }
357
358 /* reseting PCI on PCI-E cards results card to hang
359 * and always return 0xffff... so we ingore that flag
360 * for PCI-E cards */
361 bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
362
363 /* Reset chipset */
364 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
365 AR5K_RESET_CTL_BASEBAND | bus_flags);
366 if (ret) {
367 ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
368 return -EIO;
369 }
370
371 if (ah->ah_version == AR5K_AR5210)
372 udelay(2300);
373
374 /* ...wakeup again!*/
375 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
376 if (ret) {
377 ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
378 return ret;
379 }
380
381 /* ...final warm reset */
382 if (ath5k_hw_nic_reset(ah, 0)) {
383 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
384 return -EIO;
385 }
386
387 if (ah->ah_version != AR5K_AR5210) {
388 /* ...set the PHY operating mode */
389 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
390 udelay(300);
391
392 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
393 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
394 }
395
396 return 0;
397}
398
399/*
400 * Main reset function
401 */
402int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
403 struct ieee80211_channel *channel, bool change_channel)
404{
405 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
406 struct pci_dev *pdev = ah->ah_sc->pdev;
407 u32 data, s_seq, s_ant, s_led[3], dma_size;
408 unsigned int i, mode, freq, ee_mode, ant[2];
409 int ret;
410
411 ATH5K_TRACE(ah->ah_sc);
412
413 s_seq = 0;
414 s_ant = 0;
415 ee_mode = 0;
416 freq = 0;
417 mode = 0;
418
419 /*
420 * Save some registers before a reset
421 */
422 /*DCU/Antenna selection not available on 5210*/
423 if (ah->ah_version != AR5K_AR5210) {
424 if (change_channel) {
425 /* Seq number for queue 0 -do this for all queues ? */
426 s_seq = ath5k_hw_reg_read(ah,
427 AR5K_QUEUE_DFS_SEQNUM(0));
428 /*Default antenna*/
429 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
430 }
431 }
432
433 /*GPIOs*/
434 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
435 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
436 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
437
438 if (change_channel && ah->ah_rf_banks != NULL)
439 ath5k_hw_get_rf_gain(ah);
440
441
442 /*Wakeup the device*/
443 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
444 if (ret)
445 return ret;
446
447 /*
448 * Initialize operating mode
449 */
450 ah->ah_op_mode = op_mode;
451
452 /*
453 * 5111/5112 Settings
454 * 5210 only comes with RF5110
455 */
456 if (ah->ah_version != AR5K_AR5210) {
457 if (ah->ah_radio != AR5K_RF5111 &&
458 ah->ah_radio != AR5K_RF5112 &&
459 ah->ah_radio != AR5K_RF5413 &&
460 ah->ah_radio != AR5K_RF2413 &&
461 ah->ah_radio != AR5K_RF2425) {
462 ATH5K_ERR(ah->ah_sc,
463 "invalid phy radio: %u\n", ah->ah_radio);
464 return -EINVAL;
465 }
466
467 switch (channel->hw_value & CHANNEL_MODES) {
468 case CHANNEL_A:
469 mode = AR5K_MODE_11A;
470 freq = AR5K_INI_RFGAIN_5GHZ;
471 ee_mode = AR5K_EEPROM_MODE_11A;
472 break;
473 case CHANNEL_G:
474 mode = AR5K_MODE_11G;
475 freq = AR5K_INI_RFGAIN_2GHZ;
476 ee_mode = AR5K_EEPROM_MODE_11G;
477 break;
478 case CHANNEL_B:
479 mode = AR5K_MODE_11B;
480 freq = AR5K_INI_RFGAIN_2GHZ;
481 ee_mode = AR5K_EEPROM_MODE_11B;
482 break;
483 case CHANNEL_T:
484 mode = AR5K_MODE_11A_TURBO;
485 freq = AR5K_INI_RFGAIN_5GHZ;
486 ee_mode = AR5K_EEPROM_MODE_11A;
487 break;
488 /*Is this ok on 5211 too ?*/
489 case CHANNEL_TG:
490 mode = AR5K_MODE_11G_TURBO;
491 freq = AR5K_INI_RFGAIN_2GHZ;
492 ee_mode = AR5K_EEPROM_MODE_11G;
493 break;
494 case CHANNEL_XR:
495 if (ah->ah_version == AR5K_AR5211) {
496 ATH5K_ERR(ah->ah_sc,
497 "XR mode not available on 5211");
498 return -EINVAL;
499 }
500 mode = AR5K_MODE_XR;
501 freq = AR5K_INI_RFGAIN_5GHZ;
502 ee_mode = AR5K_EEPROM_MODE_11A;
503 break;
504 default:
505 ATH5K_ERR(ah->ah_sc,
506 "invalid channel: %d\n", channel->center_freq);
507 return -EINVAL;
508 }
509
510 /* PHY access enable */
511 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
512
513 }
514
515 ret = ath5k_hw_write_initvals(ah, mode, change_channel);
516 if (ret)
517 return ret;
518
519 /*
520 * 5211/5212 Specific
521 */
522 if (ah->ah_version != AR5K_AR5210) {
523 /*
524 * Write initial RF gain settings
525 * This should work for both 5111/5112
526 */
527 ret = ath5k_hw_rfgain(ah, freq);
528 if (ret)
529 return ret;
530
531 mdelay(1);
532
533 /*
534 * Write some more initial register settings
535 */
536 if (ah->ah_version == AR5K_AR5212) {
537 ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
538
539 if (channel->hw_value == CHANNEL_G)
540 if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
541 ath5k_hw_reg_write(ah, 0x00f80d80,
542 0x994c);
543 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
544 ath5k_hw_reg_write(ah, 0x00380140,
545 0x994c);
546 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
547 ath5k_hw_reg_write(ah, 0x00fc0ec0,
548 0x994c);
549 else /* 2425 */
550 ath5k_hw_reg_write(ah, 0x00fc0fc0,
551 0x994c);
552 else
553 ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
554
555 /* Some bits are disabled here, we know nothing about
556 * register 0xa228 yet, most of the times this ends up
557 * with a value 0x9b5 -haven't seen any dump with
558 * a different value- */
559 /* Got this from decompiling binary HAL */
560 data = ath5k_hw_reg_read(ah, 0xa228);
561 data &= 0xfffffdff;
562 ath5k_hw_reg_write(ah, data, 0xa228);
563
564 data = ath5k_hw_reg_read(ah, 0xa228);
565 data &= 0xfffe03ff;
566 ath5k_hw_reg_write(ah, data, 0xa228);
567 data = 0;
568
569 /* Just write 0x9b5 ? */
570 /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
571 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
572 ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
573 ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
574 }
575
576 /* Fix for first revision of the RF5112 RF chipset */
577 if (ah->ah_radio >= AR5K_RF5112 &&
578 ah->ah_radio_5ghz_revision <
579 AR5K_SREV_RAD_5112A) {
580 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
581 AR5K_PHY_CCKTXCTL);
582 if (channel->hw_value & CHANNEL_5GHZ)
583 data = 0xffb81020;
584 else
585 data = 0xffb80d20;
586 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
587 data = 0;
588 }
589
590 /*
591 * Set TX power (FIXME)
592 */
593 ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
594 if (ret)
595 return ret;
596
597 /* Write rate duration table only on AR5212 and if
598 * virtual interface has already been brought up
599 * XXX: rethink this after new mode changes to
600 * mac80211 are integrated */
601 if (ah->ah_version == AR5K_AR5212 &&
602 ah->ah_sc->vif != NULL)
603 ath5k_hw_write_rate_duration(ah, mode);
604
605 /*
606 * Write RF registers
607 */
608 ret = ath5k_hw_rfregs(ah, channel, mode);
609 if (ret)
610 return ret;
611
612 /*
613 * Configure additional registers
614 */
615
616 /* Write OFDM timings on 5212*/
617 if (ah->ah_version == AR5K_AR5212 &&
618 channel->hw_value & CHANNEL_OFDM) {
619 ret = ath5k_hw_write_ofdm_timings(ah, channel);
620 if (ret)
621 return ret;
622 }
623
624 /*Enable/disable 802.11b mode on 5111
625 (enable 2111 frequency converter + CCK)*/
626 if (ah->ah_radio == AR5K_RF5111) {
627 if (mode == AR5K_MODE_11B)
628 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
629 AR5K_TXCFG_B_MODE);
630 else
631 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
632 AR5K_TXCFG_B_MODE);
633 }
634
635 /*
636 * Set channel and calibrate the PHY
637 */
638 ret = ath5k_hw_channel(ah, channel);
639 if (ret)
640 return ret;
641
642 /* Set antenna mode */
643 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
644 ah->ah_antenna[ee_mode][0], 0xfffffc06);
645
646 /*
647 * In case a fixed antenna was set as default
648 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
649 * registers.
650 */
651 if (s_ant != 0) {
652 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
653 ant[0] = ant[1] = AR5K_ANT_FIXED_A;
654 else /* 2 - Aux */
655 ant[0] = ant[1] = AR5K_ANT_FIXED_B;
656 } else {
657 ant[0] = AR5K_ANT_FIXED_A;
658 ant[1] = AR5K_ANT_FIXED_B;
659 }
660
661 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
662 AR5K_PHY_ANT_SWITCH_TABLE_0);
663 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
664 AR5K_PHY_ANT_SWITCH_TABLE_1);
665
666 /* Commit values from EEPROM */
667 if (ah->ah_radio == AR5K_RF5111)
668 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
669 AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
670
671 ath5k_hw_reg_write(ah,
672 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
673 AR5K_PHY_NFTHRES);
674
675 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
676 (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
677 0xffffc07f);
678 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
679 (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
680 0xfffc0fff);
681 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
682 (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
683 ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
684 0xffff0000);
685
686 ath5k_hw_reg_write(ah,
687 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
688 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
689 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
690 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
691
692 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
693 ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
694 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
695 (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
696 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
697
698 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
699 AR5K_PHY_IQ_CORR_ENABLE |
700 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
701 ee->ee_q_cal[ee_mode]);
702
703 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
704 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
705 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
706 ee->ee_margin_tx_rx[ee_mode]);
707
708 } else {
709 mdelay(1);
710 /* Disable phy and wait */
711 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
712 mdelay(1);
713 }
714
715 /*
716 * Restore saved values
717 */
718 /*DCU/Antenna selection not available on 5210*/
719 if (ah->ah_version != AR5K_AR5210) {
720 ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
721 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
722 }
723 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
724 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
725 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
726
727 /*
728 * Misc
729 */
730 /* XXX: add ah->aid once mac80211 gives this to us */
731 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
732
733 ath5k_hw_set_opmode(ah);
734 /*PISR/SISR Not available on 5210*/
735 if (ah->ah_version != AR5K_AR5210) {
736 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
737 /* If we later allow tuning for this, store into sc structure */
738 data = AR5K_TUNE_RSSI_THRES |
739 AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
740 ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
741 }
742
743 /*
744 * Set Rx/Tx DMA Configuration
745 *
746 * Set maximum DMA size (512) except for PCI-E cards since
747 * it causes rx overruns and tx errors (tested on 5424 but since
748 * rx overruns also occur on 5416/5418 with madwifi we set 128
749 * for all PCI-E cards to be safe).
750 *
751 * In dumps this is 128 for allchips.
752 *
753 * XXX: need to check 5210 for this
754 * TODO: Check out tx triger level, it's always 64 on dumps but I
755 * guess we can tweak it and see how it goes ;-)
756 */
757 dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
758 if (ah->ah_version != AR5K_AR5210) {
759 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
760 AR5K_TXCFG_SDMAMR, dma_size);
761 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
762 AR5K_RXCFG_SDMAMW, dma_size);
763 }
764
765 /*
766 * Enable the PHY and wait until completion
767 */
768 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
769
770 /*
771 * On 5211+ read activation -> rx delay
772 * and use it.
773 */
774 if (ah->ah_version != AR5K_AR5210) {
775 data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
776 AR5K_PHY_RX_DELAY_M;
777 data = (channel->hw_value & CHANNEL_CCK) ?
778 ((data << 2) / 22) : (data / 10);
779
780 udelay(100 + (2 * data));
781 data = 0;
782 } else {
783 mdelay(1);
784 }
785
786 /*
787 * Perform ADC test (?)
788 */
789 data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
790 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
791 for (i = 0; i <= 20; i++) {
792 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
793 break;
794 udelay(200);
795 }
796 ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
797 data = 0;
798
799 /*
800 * Start automatic gain calibration
801 *
802 * During AGC calibration RX path is re-routed to
803 * a signal detector so we don't receive anything.
804 *
805 * This method is used to calibrate some static offsets
806 * used together with on-the fly I/Q calibration (the
807 * one performed via ath5k_hw_phy_calibrate), that doesn't
808 * interrupt rx path.
809 *
810 * If we are in a noisy environment AGC calibration may time
811 * out.
812 */
813 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
814 AR5K_PHY_AGCCTL_CAL);
815
816 /* At the same time start I/Q calibration for QAM constellation
817 * -no need for CCK- */
818 ah->ah_calibration = false;
819 if (!(mode == AR5K_MODE_11B)) {
820 ah->ah_calibration = true;
821 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
822 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
823 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
824 AR5K_PHY_IQ_RUN);
825 }
826
827 /* Wait for gain calibration to finish (we check for I/Q calibration
828 * during ath5k_phy_calibrate) */
829 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
830 AR5K_PHY_AGCCTL_CAL, 0, false)) {
831 ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
832 channel->center_freq);
833 return -EAGAIN;
834 }
835
836 /*
837 * Start noise floor calibration
838 *
839 * If we run NF calibration before AGC, it always times out.
840 * Binary HAL starts NF and AGC calibration at the same time
841 * and only waits for AGC to finish. I believe that's wrong because
842 * during NF calibration, rx path is also routed to a detector, so if
843 * it doesn't finish we won't have RX.
844 *
845 * XXX: Find an interval that's OK for all cards...
846 */
847 ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
848 if (ret)
849 return ret;
850
851 /*
852 * Reset queues and start beacon timers at the end of the reset routine
853 */
854 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
855 /*No QCU on 5210*/
856 if (ah->ah_version != AR5K_AR5210)
857 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
858
859 ret = ath5k_hw_reset_tx_queue(ah, i);
860 if (ret) {
861 ATH5K_ERR(ah->ah_sc,
862 "failed to reset TX queue #%d\n", i);
863 return ret;
864 }
865 }
866
867 /* Pre-enable interrupts on 5211/5212*/
868 if (ah->ah_version != AR5K_AR5210)
869 ath5k_hw_set_imr(ah, AR5K_INT_RX | AR5K_INT_TX |
870 AR5K_INT_FATAL);
871
872 /*
873 * Set RF kill flags if supported by the device (read from the EEPROM)
874 * Disable gpio_intr for now since it results system hang.
875 * TODO: Handle this in ath5k_intr
876 */
877#if 0
878 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
879 ath5k_hw_set_gpio_input(ah, 0);
880 ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
881 if (ah->ah_gpio[0] == 0)
882 ath5k_hw_set_gpio_intr(ah, 0, 1);
883 else
884 ath5k_hw_set_gpio_intr(ah, 0, 0);
885 }
886#endif
887
888 /*
889 * Set the 32MHz reference clock on 5212 phy clock sleep register
890 *
891 * TODO: Find out how to switch to external 32Khz clock to save power
892 */
893 if (ah->ah_version == AR5K_AR5212) {
894 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
895 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
896 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
897 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
898 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
899 ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
900
901 data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
902 data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
903 0x00000f80 : 0x00001380 ;
904 ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
905 data = 0;
906 }
907
908 if (ah->ah_version == AR5K_AR5212) {
909 ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
910 ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
911 ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
912 if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
913 ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
914 }
915
916 /*
917 * Disable beacons and reset the register
918 */
919 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
920 AR5K_BEACON_RESET_TSF);
921
922 return 0;
923}
924
925#undef _ATH5K_RESET
diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig
index 9e19dcceb3a2..80a692430413 100644
--- a/drivers/net/wireless/ath9k/Kconfig
+++ b/drivers/net/wireless/ath9k/Kconfig
@@ -1,6 +1,9 @@
1config ATH9K 1config ATH9K
2 tristate "Atheros 802.11n wireless cards support" 2 tristate "Atheros 802.11n wireless cards support"
3 depends on PCI && MAC80211 && WLAN_80211 3 depends on PCI && MAC80211 && WLAN_80211
4 select MAC80211_LEDS
5 select LEDS_CLASS
6 select NEW_LEDS
4 ---help--- 7 ---help---
5 This module adds support for wireless adapters based on 8 This module adds support for wireless adapters based on
6 Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. 9 Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index dc45eef3289a..39a4a70d0130 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1482,6 +1482,11 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1482 IEEE80211_HW_SIGNAL_DBM | 1482 IEEE80211_HW_SIGNAL_DBM |
1483 IEEE80211_HW_NOISE_DBM; 1483 IEEE80211_HW_NOISE_DBM;
1484 1484
1485 hw->wiphy->interface_modes =
1486 BIT(NL80211_IFTYPE_AP) |
1487 BIT(NL80211_IFTYPE_STATION) |
1488 BIT(NL80211_IFTYPE_ADHOC);
1489
1485 SET_IEEE80211_DEV(hw, &pdev->dev); 1490 SET_IEEE80211_DEV(hw, &pdev->dev);
1486 pci_set_drvdata(pdev, hw); 1491 pci_set_drvdata(pdev, hw);
1487 1492
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 1fa043d1802c..1f81d36f87c5 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -80,6 +80,18 @@ config B43_NPHY
80 80
81 SAY N. 81 SAY N.
82 82
83config B43_PHY_LP
84 bool "IEEE 802.11g LP-PHY support (BROKEN)"
85 depends on B43 && EXPERIMENTAL && BROKEN
86 ---help---
87 Support for the LP-PHY.
88 The LP-PHY is an IEEE 802.11g based PHY built into some notebooks
89 and embedded devices.
90
91 THIS IS BROKEN AND DOES NOT WORK YET.
92
93 SAY N.
94
83# This config option automatically enables b43 LEDS support, 95# This config option automatically enables b43 LEDS support,
84# if it's possible. 96# if it's possible.
85config B43_LEDS 97config B43_LEDS
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index fb6ffce03f0a..14a02b3aea53 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -4,7 +4,8 @@ b43-$(CONFIG_B43_NPHY) += tables_nphy.o
4b43-y += phy_common.o 4b43-y += phy_common.o
5b43-y += phy_g.o 5b43-y += phy_g.o
6b43-y += phy_a.o 6b43-y += phy_a.o
7b43-$(CONFIG_B43_NPHY) += nphy.o 7b43-$(CONFIG_B43_NPHY) += phy_n.o
8b43-$(CONFIG_B43_PHY_LP) += phy_lp.o
8b43-y += sysfs.o 9b43-y += sysfs.o
9b43-y += xmit.o 10b43-y += xmit.o
10b43-y += lo.o 11b43-y += lo.o
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 63bafc2f3f0a..c836beceb10d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -46,7 +46,7 @@
46#include "debugfs.h" 46#include "debugfs.h"
47#include "phy_common.h" 47#include "phy_common.h"
48#include "phy_g.h" 48#include "phy_g.h"
49#include "nphy.h" 49#include "phy_n.h"
50#include "dma.h" 50#include "dma.h"
51#include "pio.h" 51#include "pio.h"
52#include "sysfs.h" 52#include "sysfs.h"
@@ -1052,23 +1052,6 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
1052 } 1052 }
1053} 1053}
1054 1054
1055/* Turn the Analog ON/OFF */
1056static void b43_switch_analog(struct b43_wldev *dev, int on)
1057{
1058 switch (dev->phy.type) {
1059 case B43_PHYTYPE_A:
1060 case B43_PHYTYPE_G:
1061 b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
1062 break;
1063 case B43_PHYTYPE_N:
1064 b43_phy_write(dev, B43_NPHY_AFECTL_OVER,
1065 on ? 0 : 0x7FFF);
1066 break;
1067 default:
1068 B43_WARN_ON(1);
1069 }
1070}
1071
1072void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) 1055void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
1073{ 1056{
1074 u32 tmslow; 1057 u32 tmslow;
@@ -1091,8 +1074,12 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
1091 ssb_read32(dev->dev, SSB_TMSLOW); /* flush */ 1074 ssb_read32(dev->dev, SSB_TMSLOW); /* flush */
1092 msleep(1); 1075 msleep(1);
1093 1076
1094 /* Turn Analog ON */ 1077 /* Turn Analog ON, but only if we already know the PHY-type.
1095 b43_switch_analog(dev, 1); 1078 * This protects against very early setup where we don't know the
1079 * PHY-type, yet. wireless_core_reset will be called once again later,
1080 * when we know the PHY-type. */
1081 if (dev->phy.ops)
1082 dev->phy.ops->switch_analog(dev, 1);
1096 1083
1097 macctl = b43_read32(dev, B43_MMIO_MACCTL); 1084 macctl = b43_read32(dev, B43_MMIO_MACCTL);
1098 macctl &= ~B43_MACCTL_GMODE; 1085 macctl &= ~B43_MACCTL_GMODE;
@@ -2694,6 +2681,7 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
2694/* This is the opposite of b43_chip_init() */ 2681/* This is the opposite of b43_chip_init() */
2695static void b43_chip_exit(struct b43_wldev *dev) 2682static void b43_chip_exit(struct b43_wldev *dev)
2696{ 2683{
2684 b43_phy_exit(dev);
2697 b43_gpio_cleanup(dev); 2685 b43_gpio_cleanup(dev);
2698 /* firmware is released later */ 2686 /* firmware is released later */
2699} 2687}
@@ -2730,7 +2718,8 @@ static int b43_chip_init(struct b43_wldev *dev)
2730 if (err) 2718 if (err)
2731 goto err_gpio_clean; 2719 goto err_gpio_clean;
2732 2720
2733 b43_write16(dev, 0x03E6, 0x0000); 2721 /* Turn the Analog on and initialize the PHY. */
2722 phy->ops->switch_analog(dev, 1);
2734 err = b43_phy_init(dev); 2723 err = b43_phy_init(dev);
2735 if (err) 2724 if (err)
2736 goto err_gpio_clean; 2725 goto err_gpio_clean;
@@ -3947,12 +3936,11 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
3947 b43_dma_free(dev); 3936 b43_dma_free(dev);
3948 b43_pio_free(dev); 3937 b43_pio_free(dev);
3949 b43_chip_exit(dev); 3938 b43_chip_exit(dev);
3950 b43_switch_analog(dev, 0); 3939 dev->phy.ops->switch_analog(dev, 0);
3951 if (dev->wl->current_beacon) { 3940 if (dev->wl->current_beacon) {
3952 dev_kfree_skb_any(dev->wl->current_beacon); 3941 dev_kfree_skb_any(dev->wl->current_beacon);
3953 dev->wl->current_beacon = NULL; 3942 dev->wl->current_beacon = NULL;
3954 } 3943 }
3955 b43_phy_exit(dev);
3956 3944
3957 ssb_device_disable(dev->dev, 0); 3945 ssb_device_disable(dev->dev, 0);
3958 ssb_bus_may_powerdown(dev->dev->bus); 3946 ssb_bus_may_powerdown(dev->dev->bus);
@@ -3979,24 +3967,23 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
3979 b43_wireless_core_reset(dev, tmp); 3967 b43_wireless_core_reset(dev, tmp);
3980 } 3968 }
3981 3969
3970 /* Reset all data structures. */
3982 setup_struct_wldev_for_init(dev); 3971 setup_struct_wldev_for_init(dev);
3983 err = b43_phy_operations_setup(dev); 3972 phy->ops->prepare_structs(dev);
3984 if (err)
3985 goto err_busdown;
3986 3973
3987 /* Enable IRQ routing to this device. */ 3974 /* Enable IRQ routing to this device. */
3988 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev); 3975 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
3989 3976
3990 b43_imcfglo_timeouts_workaround(dev); 3977 b43_imcfglo_timeouts_workaround(dev);
3991 b43_bluetooth_coext_disable(dev); 3978 b43_bluetooth_coext_disable(dev);
3992 if (phy->ops->prepare) { 3979 if (phy->ops->prepare_hardware) {
3993 err = phy->ops->prepare(dev); 3980 err = phy->ops->prepare_hardware(dev);
3994 if (err) 3981 if (err)
3995 goto err_phy_exit; 3982 goto err_busdown;
3996 } 3983 }
3997 err = b43_chip_init(dev); 3984 err = b43_chip_init(dev);
3998 if (err) 3985 if (err)
3999 goto err_phy_exit; 3986 goto err_busdown;
4000 b43_shm_write16(dev, B43_SHM_SHARED, 3987 b43_shm_write16(dev, B43_SHM_SHARED,
4001 B43_SHM_SH_WLCOREREV, dev->dev->id.revision); 3988 B43_SHM_SH_WLCOREREV, dev->dev->id.revision);
4002 hf = b43_hf_read(dev); 3989 hf = b43_hf_read(dev);
@@ -4064,8 +4051,6 @@ out:
4064 4051
4065err_chip_exit: 4052err_chip_exit:
4066 b43_chip_exit(dev); 4053 b43_chip_exit(dev);
4067err_phy_exit:
4068 b43_phy_exit(dev);
4069err_busdown: 4054err_busdown:
4070 ssb_bus_may_powerdown(bus); 4055 ssb_bus_may_powerdown(bus);
4071 B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); 4056 B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
@@ -4342,6 +4327,7 @@ static void b43_wireless_core_detach(struct b43_wldev *dev)
4342 /* We release firmware that late to not be required to re-request 4327 /* We release firmware that late to not be required to re-request
4343 * is all the time when we reinit the core. */ 4328 * is all the time when we reinit the core. */
4344 b43_release_firmware(dev); 4329 b43_release_firmware(dev);
4330 b43_phy_free(dev);
4345} 4331}
4346 4332
4347static int b43_wireless_core_attach(struct b43_wldev *dev) 4333static int b43_wireless_core_attach(struct b43_wldev *dev)
@@ -4415,29 +4401,35 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
4415 } 4401 }
4416 } 4402 }
4417 4403
4404 err = b43_phy_allocate(dev);
4405 if (err)
4406 goto err_powerdown;
4407
4418 dev->phy.gmode = have_2ghz_phy; 4408 dev->phy.gmode = have_2ghz_phy;
4419 tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; 4409 tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
4420 b43_wireless_core_reset(dev, tmp); 4410 b43_wireless_core_reset(dev, tmp);
4421 4411
4422 err = b43_validate_chipaccess(dev); 4412 err = b43_validate_chipaccess(dev);
4423 if (err) 4413 if (err)
4424 goto err_powerdown; 4414 goto err_phy_free;
4425 err = b43_setup_bands(dev, have_2ghz_phy, have_5ghz_phy); 4415 err = b43_setup_bands(dev, have_2ghz_phy, have_5ghz_phy);
4426 if (err) 4416 if (err)
4427 goto err_powerdown; 4417 goto err_phy_free;
4428 4418
4429 /* Now set some default "current_dev" */ 4419 /* Now set some default "current_dev" */
4430 if (!wl->current_dev) 4420 if (!wl->current_dev)
4431 wl->current_dev = dev; 4421 wl->current_dev = dev;
4432 INIT_WORK(&dev->restart_work, b43_chip_reset); 4422 INIT_WORK(&dev->restart_work, b43_chip_reset);
4433 4423
4434 b43_switch_analog(dev, 0); 4424 dev->phy.ops->switch_analog(dev, 0);
4435 ssb_device_disable(dev->dev, 0); 4425 ssb_device_disable(dev->dev, 0);
4436 ssb_bus_may_powerdown(bus); 4426 ssb_bus_may_powerdown(bus);
4437 4427
4438out: 4428out:
4439 return err; 4429 return err;
4440 4430
4431err_phy_free:
4432 b43_phy_free(dev);
4441err_powerdown: 4433err_powerdown:
4442 ssb_bus_may_powerdown(bus); 4434 ssb_bus_may_powerdown(bus);
4443 return err; 4435 return err;
@@ -4569,6 +4561,13 @@ static int b43_wireless_init(struct ssb_device *dev)
4569 IEEE80211_HW_SIGNAL_DBM | 4561 IEEE80211_HW_SIGNAL_DBM |
4570 IEEE80211_HW_NOISE_DBM; 4562 IEEE80211_HW_NOISE_DBM;
4571 4563
4564 hw->wiphy->interface_modes =
4565 BIT(NL80211_IFTYPE_AP) |
4566 BIT(NL80211_IFTYPE_MESH_POINT) |
4567 BIT(NL80211_IFTYPE_STATION) |
4568 BIT(NL80211_IFTYPE_WDS) |
4569 BIT(NL80211_IFTYPE_ADHOC);
4570
4572 hw->queues = b43_modparam_qos ? 4 : 1; 4571 hw->queues = b43_modparam_qos ? 4 : 1;
4573 SET_IEEE80211_DEV(hw, dev->dev); 4572 SET_IEEE80211_DEV(hw, dev->dev);
4574 if (is_valid_ether_addr(sprom->et1mac)) 4573 if (is_valid_ether_addr(sprom->et1mac))
diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c
deleted file mode 100644
index 02ae450beb00..000000000000
--- a/drivers/net/wireless/b43/phy.c
+++ /dev/null
@@ -1,489 +0,0 @@
1/*
2
3 Broadcom B43 wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
7 Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
8 Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
9 Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; see the file COPYING. If not, write to
23 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
24 Boston, MA 02110-1301, USA.
25
26*/
27
28#include <linux/delay.h>
29#include <linux/io.h>
30#include <linux/types.h>
31#include <linux/bitrev.h>
32
33#include "b43.h"
34#include "phy.h"
35#include "nphy.h"
36#include "main.h"
37#include "tables.h"
38#include "lo.h"
39#include "wa.h"
40
41
42static void b43_shm_clear_tssi(struct b43_wldev *dev)
43{
44 struct b43_phy *phy = &dev->phy;
45
46 switch (phy->type) {
47 case B43_PHYTYPE_A:
48 b43_shm_write16(dev, B43_SHM_SHARED, 0x0068, 0x7F7F);
49 b43_shm_write16(dev, B43_SHM_SHARED, 0x006a, 0x7F7F);
50 break;
51 case B43_PHYTYPE_B:
52 case B43_PHYTYPE_G:
53 b43_shm_write16(dev, B43_SHM_SHARED, 0x0058, 0x7F7F);
54 b43_shm_write16(dev, B43_SHM_SHARED, 0x005a, 0x7F7F);
55 b43_shm_write16(dev, B43_SHM_SHARED, 0x0070, 0x7F7F);
56 b43_shm_write16(dev, B43_SHM_SHARED, 0x0072, 0x7F7F);
57 break;
58 }
59}
60
61/* http://bcm-specs.sipsolutions.net/EstimatePowerOut
62 * This function converts a TSSI value to dBm in Q5.2
63 */
64static s8 b43_phy_estimate_power_out(struct b43_wldev *dev, s8 tssi)
65{
66 struct b43_phy *phy = &dev->phy;
67 s8 dbm = 0;
68 s32 tmp;
69
70 tmp = (phy->tgt_idle_tssi - phy->cur_idle_tssi + tssi);
71
72 switch (phy->type) {
73 case B43_PHYTYPE_A:
74 tmp += 0x80;
75 tmp = clamp_val(tmp, 0x00, 0xFF);
76 dbm = phy->tssi2dbm[tmp];
77 //TODO: There's a FIXME on the specs
78 break;
79 case B43_PHYTYPE_B:
80 case B43_PHYTYPE_G:
81 tmp = clamp_val(tmp, 0x00, 0x3F);
82 dbm = phy->tssi2dbm[tmp];
83 break;
84 default:
85 B43_WARN_ON(1);
86 }
87
88 return dbm;
89}
90
91void b43_put_attenuation_into_ranges(struct b43_wldev *dev,
92 int *_bbatt, int *_rfatt)
93{
94 int rfatt = *_rfatt;
95 int bbatt = *_bbatt;
96 struct b43_txpower_lo_control *lo = dev->phy.lo_control;
97
98 /* Get baseband and radio attenuation values into their permitted ranges.
99 * Radio attenuation affects power level 4 times as much as baseband. */
100
101 /* Range constants */
102 const int rf_min = lo->rfatt_list.min_val;
103 const int rf_max = lo->rfatt_list.max_val;
104 const int bb_min = lo->bbatt_list.min_val;
105 const int bb_max = lo->bbatt_list.max_val;
106
107 while (1) {
108 if (rfatt > rf_max && bbatt > bb_max - 4)
109 break; /* Can not get it into ranges */
110 if (rfatt < rf_min && bbatt < bb_min + 4)
111 break; /* Can not get it into ranges */
112 if (bbatt > bb_max && rfatt > rf_max - 1)
113 break; /* Can not get it into ranges */
114 if (bbatt < bb_min && rfatt < rf_min + 1)
115 break; /* Can not get it into ranges */
116
117 if (bbatt > bb_max) {
118 bbatt -= 4;
119 rfatt += 1;
120 continue;
121 }
122 if (bbatt < bb_min) {
123 bbatt += 4;
124 rfatt -= 1;
125 continue;
126 }
127 if (rfatt > rf_max) {
128 rfatt -= 1;
129 bbatt += 4;
130 continue;
131 }
132 if (rfatt < rf_min) {
133 rfatt += 1;
134 bbatt -= 4;
135 continue;
136 }
137 break;
138 }
139
140 *_rfatt = clamp_val(rfatt, rf_min, rf_max);
141 *_bbatt = clamp_val(bbatt, bb_min, bb_max);
142}
143
144/* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */
145void b43_phy_xmitpower(struct b43_wldev *dev)
146{
147 struct ssb_bus *bus = dev->dev->bus;
148 struct b43_phy *phy = &dev->phy;
149
150 if (phy->cur_idle_tssi == 0)
151 return;
152 if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
153 (bus->boardinfo.type == SSB_BOARD_BU4306))
154 return;
155#ifdef CONFIG_B43_DEBUG
156 if (phy->manual_txpower_control)
157 return;
158#endif
159
160 switch (phy->type) {
161 case B43_PHYTYPE_A:{
162
163 //TODO: Nothing for A PHYs yet :-/
164
165 break;
166 }
167 case B43_PHYTYPE_B:
168 case B43_PHYTYPE_G:{
169 u16 tmp;
170 s8 v0, v1, v2, v3;
171 s8 average;
172 int max_pwr;
173 int desired_pwr, estimated_pwr, pwr_adjust;
174 int rfatt_delta, bbatt_delta;
175 int rfatt, bbatt;
176 u8 tx_control;
177
178 tmp = b43_shm_read16(dev, B43_SHM_SHARED, 0x0058);
179 v0 = (s8) (tmp & 0x00FF);
180 v1 = (s8) ((tmp & 0xFF00) >> 8);
181 tmp = b43_shm_read16(dev, B43_SHM_SHARED, 0x005A);
182 v2 = (s8) (tmp & 0x00FF);
183 v3 = (s8) ((tmp & 0xFF00) >> 8);
184 tmp = 0;
185
186 if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F
187 || v3 == 0x7F) {
188 tmp =
189 b43_shm_read16(dev, B43_SHM_SHARED, 0x0070);
190 v0 = (s8) (tmp & 0x00FF);
191 v1 = (s8) ((tmp & 0xFF00) >> 8);
192 tmp =
193 b43_shm_read16(dev, B43_SHM_SHARED, 0x0072);
194 v2 = (s8) (tmp & 0x00FF);
195 v3 = (s8) ((tmp & 0xFF00) >> 8);
196 if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F
197 || v3 == 0x7F)
198 return;
199 v0 = (v0 + 0x20) & 0x3F;
200 v1 = (v1 + 0x20) & 0x3F;
201 v2 = (v2 + 0x20) & 0x3F;
202 v3 = (v3 + 0x20) & 0x3F;
203 tmp = 1;
204 }
205 b43_shm_clear_tssi(dev);
206
207 average = (v0 + v1 + v2 + v3 + 2) / 4;
208
209 if (tmp
210 && (b43_shm_read16(dev, B43_SHM_SHARED, 0x005E) &
211 0x8))
212 average -= 13;
213
214 estimated_pwr =
215 b43_phy_estimate_power_out(dev, average);
216
217 max_pwr = dev->dev->bus->sprom.maxpwr_bg;
218 if ((dev->dev->bus->sprom.boardflags_lo
219 & B43_BFL_PACTRL) && (phy->type == B43_PHYTYPE_G))
220 max_pwr -= 0x3;
221 if (unlikely(max_pwr <= 0)) {
222 b43warn(dev->wl,
223 "Invalid max-TX-power value in SPROM.\n");
224 max_pwr = 60; /* fake it */
225 dev->dev->bus->sprom.maxpwr_bg = max_pwr;
226 }
227
228 /*TODO:
229 max_pwr = min(REG - dev->dev->bus->sprom.antennagain_bgphy - 0x6, max_pwr)
230 where REG is the max power as per the regulatory domain
231 */
232
233 /* Get desired power (in Q5.2) */
234 desired_pwr = INT_TO_Q52(phy->power_level);
235 /* And limit it. max_pwr already is Q5.2 */
236 desired_pwr = clamp_val(desired_pwr, 0, max_pwr);
237 if (b43_debug(dev, B43_DBG_XMITPOWER)) {
238 b43dbg(dev->wl,
239 "Current TX power output: " Q52_FMT
240 " dBm, " "Desired TX power output: "
241 Q52_FMT " dBm\n", Q52_ARG(estimated_pwr),
242 Q52_ARG(desired_pwr));
243 }
244
245 /* Calculate the adjustment delta. */
246 pwr_adjust = desired_pwr - estimated_pwr;
247
248 /* RF attenuation delta. */
249 rfatt_delta = ((pwr_adjust + 7) / 8);
250 /* Lower attenuation => Bigger power output. Negate it. */
251 rfatt_delta = -rfatt_delta;
252
253 /* Baseband attenuation delta. */
254 bbatt_delta = pwr_adjust / 2;
255 /* Lower attenuation => Bigger power output. Negate it. */
256 bbatt_delta = -bbatt_delta;
257 /* RF att affects power level 4 times as much as
258 * Baseband attennuation. Subtract it. */
259 bbatt_delta -= 4 * rfatt_delta;
260
261 /* So do we finally need to adjust something? */
262 if ((rfatt_delta == 0) && (bbatt_delta == 0))
263 return;
264
265 /* Calculate the new attenuation values. */
266 bbatt = phy->bbatt.att;
267 bbatt += bbatt_delta;
268 rfatt = phy->rfatt.att;
269 rfatt += rfatt_delta;
270
271 b43_put_attenuation_into_ranges(dev, &bbatt, &rfatt);
272 tx_control = phy->tx_control;
273 if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 2)) {
274 if (rfatt <= 1) {
275 if (tx_control == 0) {
276 tx_control =
277 B43_TXCTL_PA2DB |
278 B43_TXCTL_TXMIX;
279 rfatt += 2;
280 bbatt += 2;
281 } else if (dev->dev->bus->sprom.
282 boardflags_lo &
283 B43_BFL_PACTRL) {
284 bbatt += 4 * (rfatt - 2);
285 rfatt = 2;
286 }
287 } else if (rfatt > 4 && tx_control) {
288 tx_control = 0;
289 if (bbatt < 3) {
290 rfatt -= 3;
291 bbatt += 2;
292 } else {
293 rfatt -= 2;
294 bbatt -= 2;
295 }
296 }
297 }
298 /* Save the control values */
299 phy->tx_control = tx_control;
300 b43_put_attenuation_into_ranges(dev, &bbatt, &rfatt);
301 phy->rfatt.att = rfatt;
302 phy->bbatt.att = bbatt;
303
304 /* Adjust the hardware */
305 b43_phy_lock(dev);
306 b43_radio_lock(dev);
307 b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt,
308 phy->tx_control);
309 b43_radio_unlock(dev);
310 b43_phy_unlock(dev);
311 break;
312 }
313 case B43_PHYTYPE_N:
314 b43_nphy_xmitpower(dev);
315 break;
316 default:
317 B43_WARN_ON(1);
318 }
319}
320
321static inline s32 b43_tssi2dbm_ad(s32 num, s32 den)
322{
323 if (num < 0)
324 return num / den;
325 else
326 return (num + den / 2) / den;
327}
328
329static inline
330 s8 b43_tssi2dbm_entry(s8 entry[], u8 index, s16 pab0, s16 pab1, s16 pab2)
331{
332 s32 m1, m2, f = 256, q, delta;
333 s8 i = 0;
334
335 m1 = b43_tssi2dbm_ad(16 * pab0 + index * pab1, 32);
336 m2 = max(b43_tssi2dbm_ad(32768 + index * pab2, 256), 1);
337 do {
338 if (i > 15)
339 return -EINVAL;
340 q = b43_tssi2dbm_ad(f * 4096 -
341 b43_tssi2dbm_ad(m2 * f, 16) * f, 2048);
342 delta = abs(q - f);
343 f = q;
344 i++;
345 } while (delta >= 2);
346 entry[index] = clamp_val(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128);
347 return 0;
348}
349
350/* http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table */
351int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev)
352{
353 struct b43_phy *phy = &dev->phy;
354 s16 pab0, pab1, pab2;
355 u8 idx;
356 s8 *dyn_tssi2dbm;
357
358 if (phy->type == B43_PHYTYPE_A) {
359 pab0 = (s16) (dev->dev->bus->sprom.pa1b0);
360 pab1 = (s16) (dev->dev->bus->sprom.pa1b1);
361 pab2 = (s16) (dev->dev->bus->sprom.pa1b2);
362 } else {
363 pab0 = (s16) (dev->dev->bus->sprom.pa0b0);
364 pab1 = (s16) (dev->dev->bus->sprom.pa0b1);
365 pab2 = (s16) (dev->dev->bus->sprom.pa0b2);
366 }
367
368 if ((dev->dev->bus->chip_id == 0x4301) && (phy->radio_ver != 0x2050)) {
369 phy->tgt_idle_tssi = 0x34;
370 phy->tssi2dbm = b43_tssi2dbm_b_table;
371 return 0;
372 }
373
374 if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
375 pab0 != -1 && pab1 != -1 && pab2 != -1) {
376 /* The pabX values are set in SPROM. Use them. */
377 if (phy->type == B43_PHYTYPE_A) {
378 if ((s8) dev->dev->bus->sprom.itssi_a != 0 &&
379 (s8) dev->dev->bus->sprom.itssi_a != -1)
380 phy->tgt_idle_tssi =
381 (s8) (dev->dev->bus->sprom.itssi_a);
382 else
383 phy->tgt_idle_tssi = 62;
384 } else {
385 if ((s8) dev->dev->bus->sprom.itssi_bg != 0 &&
386 (s8) dev->dev->bus->sprom.itssi_bg != -1)
387 phy->tgt_idle_tssi =
388 (s8) (dev->dev->bus->sprom.itssi_bg);
389 else
390 phy->tgt_idle_tssi = 62;
391 }
392 dyn_tssi2dbm = kmalloc(64, GFP_KERNEL);
393 if (dyn_tssi2dbm == NULL) {
394 b43err(dev->wl, "Could not allocate memory "
395 "for tssi2dbm table\n");
396 return -ENOMEM;
397 }
398 for (idx = 0; idx < 64; idx++)
399 if (b43_tssi2dbm_entry
400 (dyn_tssi2dbm, idx, pab0, pab1, pab2)) {
401 phy->tssi2dbm = NULL;
402 b43err(dev->wl, "Could not generate "
403 "tssi2dBm table\n");
404 kfree(dyn_tssi2dbm);
405 return -ENODEV;
406 }
407 phy->tssi2dbm = dyn_tssi2dbm;
408 phy->dyn_tssi_tbl = 1;
409 } else {
410 /* pabX values not set in SPROM. */
411 switch (phy->type) {
412 case B43_PHYTYPE_A:
413 /* APHY needs a generated table. */
414 phy->tssi2dbm = NULL;
415 b43err(dev->wl, "Could not generate tssi2dBm "
416 "table (wrong SPROM info)!\n");
417 return -ENODEV;
418 case B43_PHYTYPE_B:
419 phy->tgt_idle_tssi = 0x34;
420 phy->tssi2dbm = b43_tssi2dbm_b_table;
421 break;
422 case B43_PHYTYPE_G:
423 phy->tgt_idle_tssi = 0x34;
424 phy->tssi2dbm = b43_tssi2dbm_g_table;
425 break;
426 }
427 }
428
429 return 0;
430}
431
432void b43_radio_turn_on(struct b43_wldev *dev)
433{
434 struct b43_phy *phy = &dev->phy;
435 int err;
436 u8 channel;
437
438 might_sleep();
439
440 if (phy->radio_on)
441 return;
442
443 switch (phy->type) {
444 case B43_PHYTYPE_A:
445 b43_radio_write16(dev, 0x0004, 0x00C0);
446 b43_radio_write16(dev, 0x0005, 0x0008);
447 b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) & 0xFFF7);
448 b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) & 0xFFF7);
449 b43_radio_init2060(dev);
450 break;
451 case B43_PHYTYPE_B:
452 case B43_PHYTYPE_G:
453 //XXX
454 break;
455 case B43_PHYTYPE_N:
456 b43_nphy_radio_turn_on(dev);
457 break;
458 default:
459 B43_WARN_ON(1);
460 }
461 phy->radio_on = 1;
462}
463
464void b43_radio_turn_off(struct b43_wldev *dev, bool force)
465{
466 struct b43_phy *phy = &dev->phy;
467
468 if (!phy->radio_on && !force)
469 return;
470
471 switch (phy->type) {
472 case B43_PHYTYPE_N:
473 b43_nphy_radio_turn_off(dev);
474 break;
475 case B43_PHYTYPE_A:
476 b43_radio_write16(dev, 0x0004, 0x00FF);
477 b43_radio_write16(dev, 0x0005, 0x00FB);
478 b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) | 0x0008);
479 b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008);
480 break;
481 case B43_PHYTYPE_G: {
482 //XXX
483 break;
484 }
485 default:
486 B43_WARN_ON(1);
487 }
488 phy->radio_on = 0;
489}
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 4d7d59e30960..0f1a84c9de61 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -58,6 +58,25 @@ static inline u16 freq_r3A_value(u16 frequency)
58 return value; 58 return value;
59} 59}
60 60
61#if 0
62/* This function converts a TSSI value to dBm in Q5.2 */
63static s8 b43_aphy_estimate_power_out(struct b43_wldev *dev, s8 tssi)
64{
65 struct b43_phy *phy = &dev->phy;
66 struct b43_phy_a *aphy = phy->a;
67 s8 dbm = 0;
68 s32 tmp;
69
70 tmp = (aphy->tgt_idle_tssi - aphy->cur_idle_tssi + tssi);
71 tmp += 0x80;
72 tmp = clamp_val(tmp, 0x00, 0xFF);
73 dbm = aphy->tssi2dbm[tmp];
74 //TODO: There's a FIXME on the specs
75
76 return dbm;
77}
78#endif
79
61void b43_radio_set_tx_iq(struct b43_wldev *dev) 80void b43_radio_set_tx_iq(struct b43_wldev *dev)
62{ 81{
63 static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 }; 82 static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
@@ -326,43 +345,106 @@ void b43_phy_inita(struct b43_wldev *dev)
326 } 345 }
327} 346}
328 347
348/* Initialise the TSSI->dBm lookup table */
349static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev)
350{
351 struct b43_phy *phy = &dev->phy;
352 struct b43_phy_a *aphy = phy->a;
353 s16 pab0, pab1, pab2;
354
355 pab0 = (s16) (dev->dev->bus->sprom.pa1b0);
356 pab1 = (s16) (dev->dev->bus->sprom.pa1b1);
357 pab2 = (s16) (dev->dev->bus->sprom.pa1b2);
358
359 if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
360 pab0 != -1 && pab1 != -1 && pab2 != -1) {
361 /* The pabX values are set in SPROM. Use them. */
362 if ((s8) dev->dev->bus->sprom.itssi_a != 0 &&
363 (s8) dev->dev->bus->sprom.itssi_a != -1)
364 aphy->tgt_idle_tssi =
365 (s8) (dev->dev->bus->sprom.itssi_a);
366 else
367 aphy->tgt_idle_tssi = 62;
368 aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
369 pab1, pab2);
370 if (!aphy->tssi2dbm)
371 return -ENOMEM;
372 } else {
373 /* pabX values not set in SPROM,
374 * but APHY needs a generated table. */
375 aphy->tssi2dbm = NULL;
376 b43err(dev->wl, "Could not generate tssi2dBm "
377 "table (wrong SPROM info)!\n");
378 return -ENODEV;
379 }
380
381 return 0;
382}
383
329static int b43_aphy_op_allocate(struct b43_wldev *dev) 384static int b43_aphy_op_allocate(struct b43_wldev *dev)
330{ 385{
331 struct b43_phy_a *aphy; 386 struct b43_phy_a *aphy;
387 int err;
332 388
333 aphy = kzalloc(sizeof(*aphy), GFP_KERNEL); 389 aphy = kzalloc(sizeof(*aphy), GFP_KERNEL);
334 if (!aphy) 390 if (!aphy)
335 return -ENOMEM; 391 return -ENOMEM;
336 dev->phy.a = aphy; 392 dev->phy.a = aphy;
337 393
338 //TODO init struct b43_phy_a 394 err = b43_aphy_init_tssi2dbm_table(dev);
395 if (err)
396 goto err_free_aphy;
339 397
340 return 0; 398 return 0;
399
400err_free_aphy:
401 kfree(aphy);
402 dev->phy.a = NULL;
403
404 return err;
341} 405}
342 406
343static int b43_aphy_op_init(struct b43_wldev *dev) 407static void b43_aphy_op_prepare_structs(struct b43_wldev *dev)
344{ 408{
345 struct b43_phy_a *aphy = dev->phy.a; 409 struct b43_phy *phy = &dev->phy;
410 struct b43_phy_a *aphy = phy->a;
411 const void *tssi2dbm;
412 int tgt_idle_tssi;
346 413
347 b43_phy_inita(dev); 414 /* tssi2dbm table is constant, so it is initialized at alloc time.
348 aphy->initialised = 1; 415 * Save a copy of the pointer. */
416 tssi2dbm = aphy->tssi2dbm;
417 tgt_idle_tssi = aphy->tgt_idle_tssi;
418
419 /* Zero out the whole PHY structure. */
420 memset(aphy, 0, sizeof(*aphy));
421
422 aphy->tssi2dbm = tssi2dbm;
423 aphy->tgt_idle_tssi = tgt_idle_tssi;
424
425 //TODO init struct b43_phy_a
349 426
350 return 0;
351} 427}
352 428
353static void b43_aphy_op_exit(struct b43_wldev *dev) 429static void b43_aphy_op_free(struct b43_wldev *dev)
354{ 430{
355 struct b43_phy_a *aphy = dev->phy.a; 431 struct b43_phy *phy = &dev->phy;
432 struct b43_phy_a *aphy = phy->a;
433
434 kfree(aphy->tssi2dbm);
435 aphy->tssi2dbm = NULL;
356 436
357 if (aphy->initialised) {
358 //TODO
359 aphy->initialised = 0;
360 }
361 //TODO
362 kfree(aphy); 437 kfree(aphy);
363 dev->phy.a = NULL; 438 dev->phy.a = NULL;
364} 439}
365 440
441static int b43_aphy_op_init(struct b43_wldev *dev)
442{
443 b43_phy_inita(dev);
444
445 return 0;
446}
447
366static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset) 448static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
367{ 449{
368 /* OFDM registers are base-registers for the A-PHY. */ 450 /* OFDM registers are base-registers for the A-PHY. */
@@ -430,7 +512,23 @@ static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)
430 512
431static void b43_aphy_op_software_rfkill(struct b43_wldev *dev, 513static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
432 enum rfkill_state state) 514 enum rfkill_state state)
433{//TODO 515{
516 struct b43_phy *phy = &dev->phy;
517
518 if (state == RFKILL_STATE_UNBLOCKED) {
519 if (phy->radio_on)
520 return;
521 b43_radio_write16(dev, 0x0004, 0x00C0);
522 b43_radio_write16(dev, 0x0005, 0x0008);
523 b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) & 0xFFF7);
524 b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) & 0xFFF7);
525 b43_radio_init2060(dev);
526 } else {
527 b43_radio_write16(dev, 0x0004, 0x00FF);
528 b43_radio_write16(dev, 0x0005, 0x00FB);
529 b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) | 0x0008);
530 b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008);
531 }
434} 532}
435 533
436static int b43_aphy_op_switch_channel(struct b43_wldev *dev, 534static int b43_aphy_op_switch_channel(struct b43_wldev *dev,
@@ -525,14 +623,16 @@ static void b43_aphy_op_pwork_60sec(struct b43_wldev *dev)
525 623
526const struct b43_phy_operations b43_phyops_a = { 624const struct b43_phy_operations b43_phyops_a = {
527 .allocate = b43_aphy_op_allocate, 625 .allocate = b43_aphy_op_allocate,
626 .free = b43_aphy_op_free,
627 .prepare_structs = b43_aphy_op_prepare_structs,
528 .init = b43_aphy_op_init, 628 .init = b43_aphy_op_init,
529 .exit = b43_aphy_op_exit,
530 .phy_read = b43_aphy_op_read, 629 .phy_read = b43_aphy_op_read,
531 .phy_write = b43_aphy_op_write, 630 .phy_write = b43_aphy_op_write,
532 .radio_read = b43_aphy_op_radio_read, 631 .radio_read = b43_aphy_op_radio_read,
533 .radio_write = b43_aphy_op_radio_write, 632 .radio_write = b43_aphy_op_radio_write,
534 .supports_hwpctl = b43_aphy_op_supports_hwpctl, 633 .supports_hwpctl = b43_aphy_op_supports_hwpctl,
535 .software_rfkill = b43_aphy_op_software_rfkill, 634 .software_rfkill = b43_aphy_op_software_rfkill,
635 .switch_analog = b43_phyop_switch_analog_generic,
536 .switch_channel = b43_aphy_op_switch_channel, 636 .switch_channel = b43_aphy_op_switch_channel,
537 .get_default_chan = b43_aphy_op_get_default_chan, 637 .get_default_chan = b43_aphy_op_get_default_chan,
538 .set_rx_antenna = b43_aphy_op_set_rx_antenna, 638 .set_rx_antenna = b43_aphy_op_set_rx_antenna,
diff --git a/drivers/net/wireless/b43/phy_a.h b/drivers/net/wireless/b43/phy_a.h
index e8640f7312bf..5cfaab7b16ee 100644
--- a/drivers/net/wireless/b43/phy_a.h
+++ b/drivers/net/wireless/b43/phy_a.h
@@ -103,7 +103,13 @@ void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
103 103
104 104
105struct b43_phy_a { 105struct b43_phy_a {
106 bool initialised; 106 /* Pointer to the table used to convert a
107 * TSSI value to dBm-Q5.2 */
108 const s8 *tssi2dbm;
109 /* Target idle TSSI */
110 int tgt_idle_tssi;
111 /* Current idle TSSI */
112 int cur_idle_tssi;//FIXME value currently not set
107 113
108 /* A-PHY TX Power control value. */ 114 /* A-PHY TX Power control value. */
109 u16 txpwr_offset; 115 u16 txpwr_offset;
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 5a550a7af2e9..4d4345d76abf 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -29,12 +29,13 @@
29#include "phy_common.h" 29#include "phy_common.h"
30#include "phy_g.h" 30#include "phy_g.h"
31#include "phy_a.h" 31#include "phy_a.h"
32#include "nphy.h" 32#include "phy_n.h"
33#include "phy_lp.h"
33#include "b43.h" 34#include "b43.h"
34#include "main.h" 35#include "main.h"
35 36
36 37
37int b43_phy_operations_setup(struct b43_wldev *dev) 38int b43_phy_allocate(struct b43_wldev *dev)
38{ 39{
39 struct b43_phy *phy = &(dev->phy); 40 struct b43_phy *phy = &(dev->phy);
40 int err; 41 int err;
@@ -54,7 +55,9 @@ int b43_phy_operations_setup(struct b43_wldev *dev)
54#endif 55#endif
55 break; 56 break;
56 case B43_PHYTYPE_LP: 57 case B43_PHYTYPE_LP:
57 /* FIXME: Not yet */ 58#ifdef CONFIG_B43_PHY_LP
59 phy->ops = &b43_phyops_lp;
60#endif
58 break; 61 break;
59 } 62 }
60 if (B43_WARN_ON(!phy->ops)) 63 if (B43_WARN_ON(!phy->ops))
@@ -67,6 +70,12 @@ int b43_phy_operations_setup(struct b43_wldev *dev)
67 return err; 70 return err;
68} 71}
69 72
73void b43_phy_free(struct b43_wldev *dev)
74{
75 dev->phy.ops->free(dev);
76 dev->phy.ops = NULL;
77}
78
70int b43_phy_init(struct b43_wldev *dev) 79int b43_phy_init(struct b43_wldev *dev)
71{ 80{
72 struct b43_phy *phy = &dev->phy; 81 struct b43_phy *phy = &dev->phy;
@@ -365,3 +374,8 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset)
365 374
366 return average; 375 return average;
367} 376}
377
378void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
379{
380 b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
381}
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index f8db9f40df5d..c9f5430d1d7d 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -74,11 +74,21 @@ enum b43_txpwr_result {
74/** 74/**
75 * struct b43_phy_operations - Function pointers for PHY ops. 75 * struct b43_phy_operations - Function pointers for PHY ops.
76 * 76 *
77 * @prepare: Prepare the PHY. This is called before @init. 77 * @allocate: Allocate and initialise the PHY data structures.
78 * Must not be NULL.
79 * @free: Destroy and free the PHY data structures.
80 * Must not be NULL.
81 *
82 * @prepare_structs: Prepare the PHY data structures.
83 * The data structures allocated in @allocate are
84 * initialized here.
85 * Must not be NULL.
86 * @prepare_hardware: Prepare the PHY. This is called before b43_chip_init to
87 * do some early early PHY hardware init.
78 * Can be NULL, if not required. 88 * Can be NULL, if not required.
79 * @init: Initialize the PHY. 89 * @init: Initialize the PHY.
80 * Must not be NULL. 90 * Must not be NULL.
81 * @exit: Shutdown the PHY and free all data structures. 91 * @exit: Shutdown the PHY.
82 * Can be NULL, if not required. 92 * Can be NULL, if not required.
83 * 93 *
84 * @phy_read: Read from a PHY register. 94 * @phy_read: Read from a PHY register.
@@ -98,6 +108,8 @@ enum b43_txpwr_result {
98 * RFKILL_STATE_SOFT_BLOCKED or 108 * RFKILL_STATE_SOFT_BLOCKED or
99 * RFKILL_STATE_UNBLOCKED 109 * RFKILL_STATE_UNBLOCKED
100 * Must not be NULL. 110 * Must not be NULL.
111 * @switch_analog: Turn the Analog on/off.
112 * Must not be NULL.
101 * @switch_channel: Switch the radio to another channel. 113 * @switch_channel: Switch the radio to another channel.
102 * Must not be NULL. 114 * Must not be NULL.
103 * @get_default_chan: Just returns the default channel number. 115 * @get_default_chan: Just returns the default channel number.
@@ -133,7 +145,9 @@ enum b43_txpwr_result {
133struct b43_phy_operations { 145struct b43_phy_operations {
134 /* Initialisation */ 146 /* Initialisation */
135 int (*allocate)(struct b43_wldev *dev); 147 int (*allocate)(struct b43_wldev *dev);
136 int (*prepare)(struct b43_wldev *dev); 148 void (*free)(struct b43_wldev *dev);
149 void (*prepare_structs)(struct b43_wldev *dev);
150 int (*prepare_hardware)(struct b43_wldev *dev);
137 int (*init)(struct b43_wldev *dev); 151 int (*init)(struct b43_wldev *dev);
138 void (*exit)(struct b43_wldev *dev); 152 void (*exit)(struct b43_wldev *dev);
139 153
@@ -146,6 +160,7 @@ struct b43_phy_operations {
146 /* Radio */ 160 /* Radio */
147 bool (*supports_hwpctl)(struct b43_wldev *dev); 161 bool (*supports_hwpctl)(struct b43_wldev *dev);
148 void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state); 162 void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state);
163 void (*switch_analog)(struct b43_wldev *dev, bool on);
149 int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel); 164 int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel);
150 unsigned int (*get_default_chan)(struct b43_wldev *dev); 165 unsigned int (*get_default_chan)(struct b43_wldev *dev);
151 void (*set_rx_antenna)(struct b43_wldev *dev, int antenna); 166 void (*set_rx_antenna)(struct b43_wldev *dev, int antenna);
@@ -165,6 +180,7 @@ struct b43_phy_operations {
165struct b43_phy_a; 180struct b43_phy_a;
166struct b43_phy_g; 181struct b43_phy_g;
167struct b43_phy_n; 182struct b43_phy_n;
183struct b43_phy_lp;
168 184
169struct b43_phy { 185struct b43_phy {
170 /* Hardware operation callbacks. */ 186 /* Hardware operation callbacks. */
@@ -185,6 +201,8 @@ struct b43_phy {
185 struct b43_phy_g *g; 201 struct b43_phy_g *g;
186 /* N-PHY specific information */ 202 /* N-PHY specific information */
187 struct b43_phy_n *n; 203 struct b43_phy_n *n;
204 /* LP-PHY specific information */
205 struct b43_phy_lp *lp;
188 }; 206 };
189 207
190 /* Band support flags. */ 208 /* Band support flags. */
@@ -234,10 +252,15 @@ struct b43_phy {
234 252
235 253
236/** 254/**
237 * b43_phy_operations_setup - Initialize the PHY operations datastructure 255 * b43_phy_allocate - Allocate PHY structs
238 * based on the current PHY type. 256 * Allocate the PHY data structures, based on the current dev->phy.type
257 */
258int b43_phy_allocate(struct b43_wldev *dev);
259
260/**
261 * b43_phy_free - Free PHY structs
239 */ 262 */
240int b43_phy_operations_setup(struct b43_wldev *dev); 263void b43_phy_free(struct b43_wldev *dev);
241 264
242/** 265/**
243 * b43_phy_init - Initialise the PHY 266 * b43_phy_init - Initialise the PHY
@@ -377,5 +400,14 @@ void b43_phy_txpower_adjust_work(struct work_struct *work);
377 */ 400 */
378int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset); 401int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
379 402
403/**
404 * b43_phy_switch_analog_generic - Generic PHY operation for switching the Analog.
405 *
406 * It does the switching based on the PHY0 core register.
407 * Do _not_ call this directly. Only use it as a switch_analog callback
408 * for struct b43_phy_operations.
409 */
410void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
411
380 412
381#endif /* LINUX_B43_PHY_COMMON_H_ */ 413#endif /* LINUX_B43_PHY_COMMON_H_ */
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index fce84896d34c..e8c012c9abb0 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -232,11 +232,12 @@ void b43_set_txpower_g(struct b43_wldev *dev,
232 if (unlikely(tx_bias == 0xFF)) 232 if (unlikely(tx_bias == 0xFF))
233 tx_bias = 0; 233 tx_bias = 0;
234 234
235 /* Save the values for later */ 235 /* Save the values for later. Use memmove, because it's valid
236 * to pass &gphy->rfatt as rfatt pointer argument. Same for bbatt. */
236 gphy->tx_control = tx_control; 237 gphy->tx_control = tx_control;
237 memcpy(&gphy->rfatt, rfatt, sizeof(*rfatt)); 238 memmove(&gphy->rfatt, rfatt, sizeof(*rfatt));
238 gphy->rfatt.with_padmix = !!(tx_control & B43_TXCTL_TXMIX); 239 gphy->rfatt.with_padmix = !!(tx_control & B43_TXCTL_TXMIX);
239 memcpy(&gphy->bbatt, bbatt, sizeof(*bbatt)); 240 memmove(&gphy->bbatt, bbatt, sizeof(*bbatt));
240 241
241 if (b43_debug(dev, B43_DBG_XMITPOWER)) { 242 if (b43_debug(dev, B43_DBG_XMITPOWER)) {
242 b43dbg(dev->wl, "Tuning TX-power to bbatt(%u), " 243 b43dbg(dev->wl, "Tuning TX-power to bbatt(%u), "
@@ -2634,7 +2635,7 @@ static int b43_gphy_op_allocate(struct b43_wldev *dev)
2634{ 2635{
2635 struct b43_phy_g *gphy; 2636 struct b43_phy_g *gphy;
2636 struct b43_txpower_lo_control *lo; 2637 struct b43_txpower_lo_control *lo;
2637 int err, i; 2638 int err;
2638 2639
2639 gphy = kzalloc(sizeof(*gphy), GFP_KERNEL); 2640 gphy = kzalloc(sizeof(*gphy), GFP_KERNEL);
2640 if (!gphy) { 2641 if (!gphy) {
@@ -2643,6 +2644,51 @@ static int b43_gphy_op_allocate(struct b43_wldev *dev)
2643 } 2644 }
2644 dev->phy.g = gphy; 2645 dev->phy.g = gphy;
2645 2646
2647 lo = kzalloc(sizeof(*lo), GFP_KERNEL);
2648 if (!lo) {
2649 err = -ENOMEM;
2650 goto err_free_gphy;
2651 }
2652 gphy->lo_control = lo;
2653
2654 err = b43_gphy_init_tssi2dbm_table(dev);
2655 if (err)
2656 goto err_free_lo;
2657
2658 return 0;
2659
2660err_free_lo:
2661 kfree(lo);
2662err_free_gphy:
2663 kfree(gphy);
2664error:
2665 return err;
2666}
2667
2668static void b43_gphy_op_prepare_structs(struct b43_wldev *dev)
2669{
2670 struct b43_phy *phy = &dev->phy;
2671 struct b43_phy_g *gphy = phy->g;
2672 const void *tssi2dbm;
2673 int tgt_idle_tssi;
2674 struct b43_txpower_lo_control *lo;
2675 unsigned int i;
2676
2677 /* tssi2dbm table is constant, so it is initialized at alloc time.
2678 * Save a copy of the pointer. */
2679 tssi2dbm = gphy->tssi2dbm;
2680 tgt_idle_tssi = gphy->tgt_idle_tssi;
2681 /* Save the LO pointer. */
2682 lo = gphy->lo_control;
2683
2684 /* Zero out the whole PHY structure. */
2685 memset(gphy, 0, sizeof(*gphy));
2686
2687 /* Restore pointers. */
2688 gphy->tssi2dbm = tssi2dbm;
2689 gphy->tgt_idle_tssi = tgt_idle_tssi;
2690 gphy->lo_control = lo;
2691
2646 memset(gphy->minlowsig, 0xFF, sizeof(gphy->minlowsig)); 2692 memset(gphy->minlowsig, 0xFF, sizeof(gphy->minlowsig));
2647 2693
2648 /* NRSSI */ 2694 /* NRSSI */
@@ -2661,31 +2707,28 @@ static int b43_gphy_op_allocate(struct b43_wldev *dev)
2661 2707
2662 gphy->average_tssi = 0xFF; 2708 gphy->average_tssi = 0xFF;
2663 2709
2664 lo = kzalloc(sizeof(*lo), GFP_KERNEL); 2710 /* Local Osciallator structure */
2665 if (!lo) {
2666 err = -ENOMEM;
2667 goto err_free_gphy;
2668 }
2669 gphy->lo_control = lo;
2670
2671 lo->tx_bias = 0xFF; 2711 lo->tx_bias = 0xFF;
2672 INIT_LIST_HEAD(&lo->calib_list); 2712 INIT_LIST_HEAD(&lo->calib_list);
2713}
2673 2714
2674 err = b43_gphy_init_tssi2dbm_table(dev); 2715static void b43_gphy_op_free(struct b43_wldev *dev)
2675 if (err) 2716{
2676 goto err_free_lo; 2717 struct b43_phy *phy = &dev->phy;
2718 struct b43_phy_g *gphy = phy->g;
2677 2719
2678 return 0; 2720 kfree(gphy->lo_control);
2721
2722 if (gphy->dyn_tssi_tbl)
2723 kfree(gphy->tssi2dbm);
2724 gphy->dyn_tssi_tbl = 0;
2725 gphy->tssi2dbm = NULL;
2679 2726
2680err_free_lo:
2681 kfree(lo);
2682err_free_gphy:
2683 kfree(gphy); 2727 kfree(gphy);
2684error: 2728 dev->phy.g = NULL;
2685 return err;
2686} 2729}
2687 2730
2688static int b43_gphy_op_prepare(struct b43_wldev *dev) 2731static int b43_gphy_op_prepare_hardware(struct b43_wldev *dev)
2689{ 2732{
2690 struct b43_phy *phy = &dev->phy; 2733 struct b43_phy *phy = &dev->phy;
2691 struct b43_phy_g *gphy = phy->g; 2734 struct b43_phy_g *gphy = phy->g;
@@ -2717,28 +2760,14 @@ static int b43_gphy_op_prepare(struct b43_wldev *dev)
2717 2760
2718static int b43_gphy_op_init(struct b43_wldev *dev) 2761static int b43_gphy_op_init(struct b43_wldev *dev)
2719{ 2762{
2720 struct b43_phy_g *gphy = dev->phy.g;
2721
2722 b43_phy_initg(dev); 2763 b43_phy_initg(dev);
2723 gphy->initialised = 1;
2724 2764
2725 return 0; 2765 return 0;
2726} 2766}
2727 2767
2728static void b43_gphy_op_exit(struct b43_wldev *dev) 2768static void b43_gphy_op_exit(struct b43_wldev *dev)
2729{ 2769{
2730 struct b43_phy_g *gphy = dev->phy.g;
2731
2732 if (gphy->initialised) {
2733 //TODO
2734 gphy->initialised = 0;
2735 }
2736 b43_lo_g_cleanup(dev); 2770 b43_lo_g_cleanup(dev);
2737 kfree(gphy->lo_control);
2738 if (gphy->dyn_tssi_tbl)
2739 kfree(gphy->tssi2dbm);
2740 kfree(gphy);
2741 dev->phy.g = NULL;
2742} 2771}
2743 2772
2744static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg) 2773static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
@@ -3231,7 +3260,9 @@ static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev)
3231 3260
3232const struct b43_phy_operations b43_phyops_g = { 3261const struct b43_phy_operations b43_phyops_g = {
3233 .allocate = b43_gphy_op_allocate, 3262 .allocate = b43_gphy_op_allocate,
3234 .prepare = b43_gphy_op_prepare, 3263 .free = b43_gphy_op_free,
3264 .prepare_structs = b43_gphy_op_prepare_structs,
3265 .prepare_hardware = b43_gphy_op_prepare_hardware,
3235 .init = b43_gphy_op_init, 3266 .init = b43_gphy_op_init,
3236 .exit = b43_gphy_op_exit, 3267 .exit = b43_gphy_op_exit,
3237 .phy_read = b43_gphy_op_read, 3268 .phy_read = b43_gphy_op_read,
@@ -3240,6 +3271,7 @@ const struct b43_phy_operations b43_phyops_g = {
3240 .radio_write = b43_gphy_op_radio_write, 3271 .radio_write = b43_gphy_op_radio_write,
3241 .supports_hwpctl = b43_gphy_op_supports_hwpctl, 3272 .supports_hwpctl = b43_gphy_op_supports_hwpctl,
3242 .software_rfkill = b43_gphy_op_software_rfkill, 3273 .software_rfkill = b43_gphy_op_software_rfkill,
3274 .switch_analog = b43_phyop_switch_analog_generic,
3243 .switch_channel = b43_gphy_op_switch_channel, 3275 .switch_channel = b43_gphy_op_switch_channel,
3244 .get_default_chan = b43_gphy_op_get_default_chan, 3276 .get_default_chan = b43_gphy_op_get_default_chan,
3245 .set_rx_antenna = b43_gphy_op_set_rx_antenna, 3277 .set_rx_antenna = b43_gphy_op_set_rx_antenna,
diff --git a/drivers/net/wireless/b43/phy_g.h b/drivers/net/wireless/b43/phy_g.h
index 7f95edea1c63..718947fd41ae 100644
--- a/drivers/net/wireless/b43/phy_g.h
+++ b/drivers/net/wireless/b43/phy_g.h
@@ -114,8 +114,6 @@ static inline bool b43_compare_bbatt(const struct b43_bbatt *a,
114struct b43_txpower_lo_control; 114struct b43_txpower_lo_control;
115 115
116struct b43_phy_g { 116struct b43_phy_g {
117 bool initialised;
118
119 /* ACI (adjacent channel interference) flags. */ 117 /* ACI (adjacent channel interference) flags. */
120 bool aci_enable; 118 bool aci_enable;
121 bool aci_wlan_automatic; 119 bool aci_wlan_automatic;
@@ -202,6 +200,8 @@ void b43_gphy_set_baseband_attenuation(struct b43_wldev *dev,
202void b43_gphy_channel_switch(struct b43_wldev *dev, 200void b43_gphy_channel_switch(struct b43_wldev *dev,
203 unsigned int channel, 201 unsigned int channel,
204 bool synthetic_pu_workaround); 202 bool synthetic_pu_workaround);
203u8 * b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
204 s16 pab0, s16 pab1, s16 pab2);
205 205
206struct b43_phy_operations; 206struct b43_phy_operations;
207extern const struct b43_phy_operations b43_phyops_g; 207extern const struct b43_phy_operations b43_phyops_g;
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
new file mode 100644
index 000000000000..c5d9dc3667c0
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -0,0 +1,155 @@
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11g LP-PHY driver
5
6 Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22
23*/
24
25#include "b43.h"
26#include "phy_lp.h"
27#include "phy_common.h"
28
29
30static int b43_lpphy_op_allocate(struct b43_wldev *dev)
31{
32 struct b43_phy_lp *lpphy;
33
34 lpphy = kzalloc(sizeof(*lpphy), GFP_KERNEL);
35 if (!lpphy)
36 return -ENOMEM;
37 dev->phy.lp = lpphy;
38
39 return 0;
40}
41
42static void b43_lpphy_op_prepare_structs(struct b43_wldev *dev)
43{
44 struct b43_phy *phy = &dev->phy;
45 struct b43_phy_lp *lpphy = phy->lp;
46
47 memset(lpphy, 0, sizeof(*lpphy));
48
49 //TODO
50}
51
52static void b43_lpphy_op_free(struct b43_wldev *dev)
53{
54 struct b43_phy_lp *lpphy = dev->phy.lp;
55
56 kfree(lpphy);
57 dev->phy.lp = NULL;
58}
59
60static int b43_lpphy_op_init(struct b43_wldev *dev)
61{
62 //TODO
63
64 return 0;
65}
66
67static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg)
68{
69 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
70 return b43_read16(dev, B43_MMIO_PHY_DATA);
71}
72
73static void b43_lpphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
74{
75 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
76 b43_write16(dev, B43_MMIO_PHY_DATA, value);
77}
78
79static u16 b43_lpphy_op_radio_read(struct b43_wldev *dev, u16 reg)
80{
81 /* Register 1 is a 32-bit register. */
82 B43_WARN_ON(reg == 1);
83 /* LP-PHY needs a special bit set for read access */
84 if (dev->phy.rev < 2) {
85 if (reg != 0x4001)
86 reg |= 0x100;
87 } else
88 reg |= 0x200;
89
90 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
91 return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
92}
93
94static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
95{
96 /* Register 1 is a 32-bit register. */
97 B43_WARN_ON(reg == 1);
98
99 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
100 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
101}
102
103static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
104 enum rfkill_state state)
105{
106 //TODO
107}
108
109static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
110 unsigned int new_channel)
111{
112 //TODO
113 return 0;
114}
115
116static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
117{
118 return 1; /* Default to channel 1 */
119}
120
121static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
122{
123 //TODO
124}
125
126static void b43_lpphy_op_adjust_txpower(struct b43_wldev *dev)
127{
128 //TODO
129}
130
131static enum b43_txpwr_result b43_lpphy_op_recalc_txpower(struct b43_wldev *dev,
132 bool ignore_tssi)
133{
134 //TODO
135 return B43_TXPWR_RES_DONE;
136}
137
138
139const struct b43_phy_operations b43_phyops_lp = {
140 .allocate = b43_lpphy_op_allocate,
141 .free = b43_lpphy_op_free,
142 .prepare_structs = b43_lpphy_op_prepare_structs,
143 .init = b43_lpphy_op_init,
144 .phy_read = b43_lpphy_op_read,
145 .phy_write = b43_lpphy_op_write,
146 .radio_read = b43_lpphy_op_radio_read,
147 .radio_write = b43_lpphy_op_radio_write,
148 .software_rfkill = b43_lpphy_op_software_rfkill,
149 .switch_analog = b43_phyop_switch_analog_generic,
150 .switch_channel = b43_lpphy_op_switch_channel,
151 .get_default_chan = b43_lpphy_op_get_default_chan,
152 .set_rx_antenna = b43_lpphy_op_set_rx_antenna,
153 .recalc_txpower = b43_lpphy_op_recalc_txpower,
154 .adjust_txpower = b43_lpphy_op_adjust_txpower,
155};
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
new file mode 100644
index 000000000000..b0b5357abf93
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -0,0 +1,540 @@
1#ifndef LINUX_B43_PHY_LP_H_
2#define LINUX_B43_PHY_LP_H_
3
4/* Definitions for the LP-PHY */
5
6
7
8
9#define B43_LP_RADIO(radio_reg) (radio_reg)
10#define B43_LP_NORTH(radio_reg) B43_LP_RADIO(radio_reg)
11#define B43_LP_SOUTH(radio_reg) B43_LP_RADIO((radio_reg) | 0x4000)
12
13
14/*** Broadcom 2062 NORTH radio registers ***/
15#define B2062_N_COMM1 B43_LP_NORTH(0x000) /* Common 01 (north) */
16#define B2062_N_COMM2 B43_LP_NORTH(0x002) /* Common 02 (north) */
17#define B2062_N_COMM3 B43_LP_NORTH(0x003) /* Common 03 (north) */
18#define B2062_N_COMM4 B43_LP_NORTH(0x004) /* Common 04 (north) */
19#define B2062_N_COMM5 B43_LP_NORTH(0x005) /* Common 05 (north) */
20#define B2062_N_COMM6 B43_LP_NORTH(0x006) /* Common 06 (north) */
21#define B2062_N_COMM7 B43_LP_NORTH(0x007) /* Common 07 (north) */
22#define B2062_N_COMM8 B43_LP_NORTH(0x008) /* Common 08 (north) */
23#define B2062_N_COMM9 B43_LP_NORTH(0x009) /* Common 09 (north) */
24#define B2062_N_COMM10 B43_LP_NORTH(0x00A) /* Common 10 (north) */
25#define B2062_N_COMM11 B43_LP_NORTH(0x00B) /* Common 11 (north) */
26#define B2062_N_COMM12 B43_LP_NORTH(0x00C) /* Common 12 (north) */
27#define B2062_N_COMM13 B43_LP_NORTH(0x00D) /* Common 13 (north) */
28#define B2062_N_COMM14 B43_LP_NORTH(0x00E) /* Common 14 (north) */
29#define B2062_N_COMM15 B43_LP_NORTH(0x00F) /* Common 15 (north) */
30#define B2062_N_PDN_CTL0 B43_LP_NORTH(0x010) /* PDN Control 0 (north) */
31#define B2062_N_PDN_CTL1 B43_LP_NORTH(0x011) /* PDN Control 1 (north) */
32#define B2062_N_PDN_CTL2 B43_LP_NORTH(0x012) /* PDN Control 2 (north) */
33#define B2062_N_PDN_CTL3 B43_LP_NORTH(0x013) /* PDN Control 3 (north) */
34#define B2062_N_PDN_CTL4 B43_LP_NORTH(0x014) /* PDN Control 4 (north) */
35#define B2062_N_GEN_CTL0 B43_LP_NORTH(0x015) /* GEN Control 0 (north) */
36#define B2062_N_IQ_CALIB B43_LP_NORTH(0x016) /* IQ Calibration (north) */
37#define B2062_N_LGENC B43_LP_NORTH(0x017) /* LGENC (north) */
38#define B2062_N_LGENA_LPF B43_LP_NORTH(0x018) /* LGENA LPF (north) */
39#define B2062_N_LGENA_BIAS0 B43_LP_NORTH(0x019) /* LGENA Bias 0 (north) */
40#define B2062_N_LGNEA_BIAS1 B43_LP_NORTH(0x01A) /* LGNEA Bias 1 (north) */
41#define B2062_N_LGENA_CTL0 B43_LP_NORTH(0x01B) /* LGENA Control 0 (north) */
42#define B2062_N_LGENA_CTL1 B43_LP_NORTH(0x01C) /* LGENA Control 1 (north) */
43#define B2062_N_LGENA_CTL2 B43_LP_NORTH(0x01D) /* LGENA Control 2 (north) */
44#define B2062_N_LGENA_TUNE0 B43_LP_NORTH(0x01E) /* LGENA Tune 0 (north) */
45#define B2062_N_LGENA_TUNE1 B43_LP_NORTH(0x01F) /* LGENA Tune 1 (north) */
46#define B2062_N_LGENA_TUNE2 B43_LP_NORTH(0x020) /* LGENA Tune 2 (north) */
47#define B2062_N_LGENA_TUNE3 B43_LP_NORTH(0x021) /* LGENA Tune 3 (north) */
48#define B2062_N_LGENA_CTL3 B43_LP_NORTH(0x022) /* LGENA Control 3 (north) */
49#define B2062_N_LGENA_CTL4 B43_LP_NORTH(0x023) /* LGENA Control 4 (north) */
50#define B2062_N_LGENA_CTL5 B43_LP_NORTH(0x024) /* LGENA Control 5 (north) */
51#define B2062_N_LGENA_CTL6 B43_LP_NORTH(0x025) /* LGENA Control 6 (north) */
52#define B2062_N_LGENA_CTL7 B43_LP_NORTH(0x026) /* LGENA Control 7 (north) */
53#define B2062_N_RXA_CTL0 B43_LP_NORTH(0x027) /* RXA Control 0 (north) */
54#define B2062_N_RXA_CTL1 B43_LP_NORTH(0x028) /* RXA Control 1 (north) */
55#define B2062_N_RXA_CTL2 B43_LP_NORTH(0x029) /* RXA Control 2 (north) */
56#define B2062_N_RXA_CTL3 B43_LP_NORTH(0x02A) /* RXA Control 3 (north) */
57#define B2062_N_RXA_CTL4 B43_LP_NORTH(0x02B) /* RXA Control 4 (north) */
58#define B2062_N_RXA_CTL5 B43_LP_NORTH(0x02C) /* RXA Control 5 (north) */
59#define B2062_N_RXA_CTL6 B43_LP_NORTH(0x02D) /* RXA Control 6 (north) */
60#define B2062_N_RXA_CTL7 B43_LP_NORTH(0x02E) /* RXA Control 7 (north) */
61#define B2062_N_RXBB_CTL0 B43_LP_NORTH(0x02F) /* RXBB Control 0 (north) */
62#define B2062_N_RXBB_CTL1 B43_LP_NORTH(0x030) /* RXBB Control 1 (north) */
63#define B2062_N_RXBB_CTL2 B43_LP_NORTH(0x031) /* RXBB Control 2 (north) */
64#define B2062_N_RXBB_GAIN0 B43_LP_NORTH(0x032) /* RXBB Gain 0 (north) */
65#define B2062_N_RXBB_GAIN1 B43_LP_NORTH(0x033) /* RXBB Gain 1 (north) */
66#define B2062_N_RXBB_GAIN2 B43_LP_NORTH(0x034) /* RXBB Gain 2 (north) */
67#define B2062_N_RXBB_GAIN3 B43_LP_NORTH(0x035) /* RXBB Gain 3 (north) */
68#define B2062_N_RXBB_RSSI0 B43_LP_NORTH(0x036) /* RXBB RSSI 0 (north) */
69#define B2062_N_RXBB_RSSI1 B43_LP_NORTH(0x037) /* RXBB RSSI 1 (north) */
70#define B2062_N_RXBB_CALIB0 B43_LP_NORTH(0x038) /* RXBB Calibration0 (north) */
71#define B2062_N_RXBB_CALIB1 B43_LP_NORTH(0x039) /* RXBB Calibration1 (north) */
72#define B2062_N_RXBB_CALIB2 B43_LP_NORTH(0x03A) /* RXBB Calibration2 (north) */
73#define B2062_N_RXBB_BIAS0 B43_LP_NORTH(0x03B) /* RXBB Bias 0 (north) */
74#define B2062_N_RXBB_BIAS1 B43_LP_NORTH(0x03C) /* RXBB Bias 1 (north) */
75#define B2062_N_RXBB_BIAS2 B43_LP_NORTH(0x03D) /* RXBB Bias 2 (north) */
76#define B2062_N_RXBB_BIAS3 B43_LP_NORTH(0x03E) /* RXBB Bias 3 (north) */
77#define B2062_N_RXBB_BIAS4 B43_LP_NORTH(0x03F) /* RXBB Bias 4 (north) */
78#define B2062_N_RXBB_BIAS5 B43_LP_NORTH(0x040) /* RXBB Bias 5 (north) */
79#define B2062_N_RXBB_RSSI2 B43_LP_NORTH(0x041) /* RXBB RSSI 2 (north) */
80#define B2062_N_RXBB_RSSI3 B43_LP_NORTH(0x042) /* RXBB RSSI 3 (north) */
81#define B2062_N_RXBB_RSSI4 B43_LP_NORTH(0x043) /* RXBB RSSI 4 (north) */
82#define B2062_N_RXBB_RSSI5 B43_LP_NORTH(0x044) /* RXBB RSSI 5 (north) */
83#define B2062_N_TX_CTL0 B43_LP_NORTH(0x045) /* TX Control 0 (north) */
84#define B2062_N_TX_CTL1 B43_LP_NORTH(0x046) /* TX Control 1 (north) */
85#define B2062_N_TX_CTL2 B43_LP_NORTH(0x047) /* TX Control 2 (north) */
86#define B2062_N_TX_CTL3 B43_LP_NORTH(0x048) /* TX Control 3 (north) */
87#define B2062_N_TX_CTL4 B43_LP_NORTH(0x049) /* TX Control 4 (north) */
88#define B2062_N_TX_CTL5 B43_LP_NORTH(0x04A) /* TX Control 5 (north) */
89#define B2062_N_TX_CTL6 B43_LP_NORTH(0x04B) /* TX Control 6 (north) */
90#define B2062_N_TX_CTL7 B43_LP_NORTH(0x04C) /* TX Control 7 (north) */
91#define B2062_N_TX_CTL8 B43_LP_NORTH(0x04D) /* TX Control 8 (north) */
92#define B2062_N_TX_CTL9 B43_LP_NORTH(0x04E) /* TX Control 9 (north) */
93#define B2062_N_TX_CTL_A B43_LP_NORTH(0x04F) /* TX Control A (north) */
94#define B2062_N_TX_GC2G B43_LP_NORTH(0x050) /* TX GC2G (north) */
95#define B2062_N_TX_GC5G B43_LP_NORTH(0x051) /* TX GC5G (north) */
96#define B2062_N_TX_TUNE B43_LP_NORTH(0x052) /* TX Tune (north) */
97#define B2062_N_TX_PAD B43_LP_NORTH(0x053) /* TX PAD (north) */
98#define B2062_N_TX_PGA B43_LP_NORTH(0x054) /* TX PGA (north) */
99#define B2062_N_TX_PADAUX B43_LP_NORTH(0x055) /* TX PADAUX (north) */
100#define B2062_N_TX_PGAAUX B43_LP_NORTH(0x056) /* TX PGAAUX (north) */
101#define B2062_N_TSSI_CTL0 B43_LP_NORTH(0x057) /* TSSI Control 0 (north) */
102#define B2062_N_TSSI_CTL1 B43_LP_NORTH(0x058) /* TSSI Control 1 (north) */
103#define B2062_N_TSSI_CTL2 B43_LP_NORTH(0x059) /* TSSI Control 2 (north) */
104#define B2062_N_IQ_CALIB_CTL0 B43_LP_NORTH(0x05A) /* IQ Calibration Control 0 (north) */
105#define B2062_N_IQ_CALIB_CTL1 B43_LP_NORTH(0x05B) /* IQ Calibration Control 1 (north) */
106#define B2062_N_IQ_CALIB_CTL2 B43_LP_NORTH(0x05C) /* IQ Calibration Control 2 (north) */
107#define B2062_N_CALIB_TS B43_LP_NORTH(0x05D) /* Calibration TS (north) */
108#define B2062_N_CALIB_CTL0 B43_LP_NORTH(0x05E) /* Calibration Control 0 (north) */
109#define B2062_N_CALIB_CTL1 B43_LP_NORTH(0x05F) /* Calibration Control 1 (north) */
110#define B2062_N_CALIB_CTL2 B43_LP_NORTH(0x060) /* Calibration Control 2 (north) */
111#define B2062_N_CALIB_CTL3 B43_LP_NORTH(0x061) /* Calibration Control 3 (north) */
112#define B2062_N_CALIB_CTL4 B43_LP_NORTH(0x062) /* Calibration Control 4 (north) */
113#define B2062_N_CALIB_DBG0 B43_LP_NORTH(0x063) /* Calibration Debug 0 (north) */
114#define B2062_N_CALIB_DBG1 B43_LP_NORTH(0x064) /* Calibration Debug 1 (north) */
115#define B2062_N_CALIB_DBG2 B43_LP_NORTH(0x065) /* Calibration Debug 2 (north) */
116#define B2062_N_CALIB_DBG3 B43_LP_NORTH(0x066) /* Calibration Debug 3 (north) */
117#define B2062_N_PSENSE_CTL0 B43_LP_NORTH(0x069) /* PSENSE Control 0 (north) */
118#define B2062_N_PSENSE_CTL1 B43_LP_NORTH(0x06A) /* PSENSE Control 1 (north) */
119#define B2062_N_PSENSE_CTL2 B43_LP_NORTH(0x06B) /* PSENSE Control 2 (north) */
120#define B2062_N_TEST_BUF0 B43_LP_NORTH(0x06C) /* TEST BUF0 (north) */
121
122/*** Broadcom 2062 SOUTH radio registers ***/
123#define B2062_S_COMM1 B43_LP_SOUTH(0x000) /* Common 01 (south) */
124#define B2062_S_RADIO_ID_CODE B43_LP_SOUTH(0x001) /* Radio ID code (south) */
125#define B2062_S_COMM2 B43_LP_SOUTH(0x002) /* Common 02 (south) */
126#define B2062_S_COMM3 B43_LP_SOUTH(0x003) /* Common 03 (south) */
127#define B2062_S_COMM4 B43_LP_SOUTH(0x004) /* Common 04 (south) */
128#define B2062_S_COMM5 B43_LP_SOUTH(0x005) /* Common 05 (south) */
129#define B2062_S_COMM6 B43_LP_SOUTH(0x006) /* Common 06 (south) */
130#define B2062_S_COMM7 B43_LP_SOUTH(0x007) /* Common 07 (south) */
131#define B2062_S_COMM8 B43_LP_SOUTH(0x008) /* Common 08 (south) */
132#define B2062_S_COMM9 B43_LP_SOUTH(0x009) /* Common 09 (south) */
133#define B2062_S_COMM10 B43_LP_SOUTH(0x00A) /* Common 10 (south) */
134#define B2062_S_COMM11 B43_LP_SOUTH(0x00B) /* Common 11 (south) */
135#define B2062_S_COMM12 B43_LP_SOUTH(0x00C) /* Common 12 (south) */
136#define B2062_S_COMM13 B43_LP_SOUTH(0x00D) /* Common 13 (south) */
137#define B2062_S_COMM14 B43_LP_SOUTH(0x00E) /* Common 14 (south) */
138#define B2062_S_COMM15 B43_LP_SOUTH(0x00F) /* Common 15 (south) */
139#define B2062_S_PDS_CTL0 B43_LP_SOUTH(0x010) /* PDS Control 0 (south) */
140#define B2062_S_PDS_CTL1 B43_LP_SOUTH(0x011) /* PDS Control 1 (south) */
141#define B2062_S_PDS_CTL2 B43_LP_SOUTH(0x012) /* PDS Control 2 (south) */
142#define B2062_S_PDS_CTL3 B43_LP_SOUTH(0x013) /* PDS Control 3 (south) */
143#define B2062_S_BG_CTL0 B43_LP_SOUTH(0x014) /* BG Control 0 (south) */
144#define B2062_S_BG_CTL1 B43_LP_SOUTH(0x015) /* BG Control 1 (south) */
145#define B2062_S_BG_CTL2 B43_LP_SOUTH(0x016) /* BG Control 2 (south) */
146#define B2062_S_LGENG_CTL0 B43_LP_SOUTH(0x017) /* LGENG Control 00 (south) */
147#define B2062_S_LGENG_CTL1 B43_LP_SOUTH(0x018) /* LGENG Control 01 (south) */
148#define B2062_S_LGENG_CTL2 B43_LP_SOUTH(0x019) /* LGENG Control 02 (south) */
149#define B2062_S_LGENG_CTL3 B43_LP_SOUTH(0x01A) /* LGENG Control 03 (south) */
150#define B2062_S_LGENG_CTL4 B43_LP_SOUTH(0x01B) /* LGENG Control 04 (south) */
151#define B2062_S_LGENG_CTL5 B43_LP_SOUTH(0x01C) /* LGENG Control 05 (south) */
152#define B2062_S_LGENG_CTL6 B43_LP_SOUTH(0x01D) /* LGENG Control 06 (south) */
153#define B2062_S_LGENG_CTL7 B43_LP_SOUTH(0x01E) /* LGENG Control 07 (south) */
154#define B2062_S_LGENG_CTL8 B43_LP_SOUTH(0x01F) /* LGENG Control 08 (south) */
155#define B2062_S_LGENG_CTL9 B43_LP_SOUTH(0x020) /* LGENG Control 09 (south) */
156#define B2062_S_LGENG_CTL10 B43_LP_SOUTH(0x021) /* LGENG Control 10 (south) */
157#define B2062_S_LGENG_CTL11 B43_LP_SOUTH(0x022) /* LGENG Control 11 (south) */
158#define B2062_S_REFPLL_CTL0 B43_LP_SOUTH(0x023) /* REFPLL Control 00 (south) */
159#define B2062_S_REFPLL_CTL1 B43_LP_SOUTH(0x024) /* REFPLL Control 01 (south) */
160#define B2062_S_REFPLL_CTL2 B43_LP_SOUTH(0x025) /* REFPLL Control 02 (south) */
161#define B2062_S_REFPLL_CTL3 B43_LP_SOUTH(0x026) /* REFPLL Control 03 (south) */
162#define B2062_S_REFPLL_CTL4 B43_LP_SOUTH(0x027) /* REFPLL Control 04 (south) */
163#define B2062_S_REFPLL_CTL5 B43_LP_SOUTH(0x028) /* REFPLL Control 05 (south) */
164#define B2062_S_REFPLL_CTL6 B43_LP_SOUTH(0x029) /* REFPLL Control 06 (south) */
165#define B2062_S_REFPLL_CTL7 B43_LP_SOUTH(0x02A) /* REFPLL Control 07 (south) */
166#define B2062_S_REFPLL_CTL8 B43_LP_SOUTH(0x02B) /* REFPLL Control 08 (south) */
167#define B2062_S_REFPLL_CTL9 B43_LP_SOUTH(0x02C) /* REFPLL Control 09 (south) */
168#define B2062_S_REFPLL_CTL10 B43_LP_SOUTH(0x02D) /* REFPLL Control 10 (south) */
169#define B2062_S_REFPLL_CTL11 B43_LP_SOUTH(0x02E) /* REFPLL Control 11 (south) */
170#define B2062_S_REFPLL_CTL12 B43_LP_SOUTH(0x02F) /* REFPLL Control 12 (south) */
171#define B2062_S_REFPLL_CTL13 B43_LP_SOUTH(0x030) /* REFPLL Control 13 (south) */
172#define B2062_S_REFPLL_CTL14 B43_LP_SOUTH(0x031) /* REFPLL Control 14 (south) */
173#define B2062_S_REFPLL_CTL15 B43_LP_SOUTH(0x032) /* REFPLL Control 15 (south) */
174#define B2062_S_REFPLL_CTL16 B43_LP_SOUTH(0x033) /* REFPLL Control 16 (south) */
175#define B2062_S_RFPLL_CTL0 B43_LP_SOUTH(0x034) /* RFPLL Control 00 (south) */
176#define B2062_S_RFPLL_CTL1 B43_LP_SOUTH(0x035) /* RFPLL Control 01 (south) */
177#define B2062_S_RFPLL_CTL2 B43_LP_SOUTH(0x036) /* RFPLL Control 02 (south) */
178#define B2062_S_RFPLL_CTL3 B43_LP_SOUTH(0x037) /* RFPLL Control 03 (south) */
179#define B2062_S_RFPLL_CTL4 B43_LP_SOUTH(0x038) /* RFPLL Control 04 (south) */
180#define B2062_S_RFPLL_CTL5 B43_LP_SOUTH(0x039) /* RFPLL Control 05 (south) */
181#define B2062_S_RFPLL_CTL6 B43_LP_SOUTH(0x03A) /* RFPLL Control 06 (south) */
182#define B2062_S_RFPLL_CTL7 B43_LP_SOUTH(0x03B) /* RFPLL Control 07 (south) */
183#define B2062_S_RFPLL_CTL8 B43_LP_SOUTH(0x03C) /* RFPLL Control 08 (south) */
184#define B2062_S_RFPLL_CTL9 B43_LP_SOUTH(0x03D) /* RFPLL Control 09 (south) */
185#define B2062_S_RFPLL_CTL10 B43_LP_SOUTH(0x03E) /* RFPLL Control 10 (south) */
186#define B2062_S_RFPLL_CTL11 B43_LP_SOUTH(0x03F) /* RFPLL Control 11 (south) */
187#define B2062_S_RFPLL_CTL12 B43_LP_SOUTH(0x040) /* RFPLL Control 12 (south) */
188#define B2062_S_RFPLL_CTL13 B43_LP_SOUTH(0x041) /* RFPLL Control 13 (south) */
189#define B2062_S_RFPLL_CTL14 B43_LP_SOUTH(0x042) /* RFPLL Control 14 (south) */
190#define B2062_S_RFPLL_CTL15 B43_LP_SOUTH(0x043) /* RFPLL Control 15 (south) */
191#define B2062_S_RFPLL_CTL16 B43_LP_SOUTH(0x044) /* RFPLL Control 16 (south) */
192#define B2062_S_RFPLL_CTL17 B43_LP_SOUTH(0x045) /* RFPLL Control 17 (south) */
193#define B2062_S_RFPLL_CTL18 B43_LP_SOUTH(0x046) /* RFPLL Control 18 (south) */
194#define B2062_S_RFPLL_CTL19 B43_LP_SOUTH(0x047) /* RFPLL Control 19 (south) */
195#define B2062_S_RFPLL_CTL20 B43_LP_SOUTH(0x048) /* RFPLL Control 20 (south) */
196#define B2062_S_RFPLL_CTL21 B43_LP_SOUTH(0x049) /* RFPLL Control 21 (south) */
197#define B2062_S_RFPLL_CTL22 B43_LP_SOUTH(0x04A) /* RFPLL Control 22 (south) */
198#define B2062_S_RFPLL_CTL23 B43_LP_SOUTH(0x04B) /* RFPLL Control 23 (south) */
199#define B2062_S_RFPLL_CTL24 B43_LP_SOUTH(0x04C) /* RFPLL Control 24 (south) */
200#define B2062_S_RFPLL_CTL25 B43_LP_SOUTH(0x04D) /* RFPLL Control 25 (south) */
201#define B2062_S_RFPLL_CTL26 B43_LP_SOUTH(0x04E) /* RFPLL Control 26 (south) */
202#define B2062_S_RFPLL_CTL27 B43_LP_SOUTH(0x04F) /* RFPLL Control 27 (south) */
203#define B2062_S_RFPLL_CTL28 B43_LP_SOUTH(0x050) /* RFPLL Control 28 (south) */
204#define B2062_S_RFPLL_CTL29 B43_LP_SOUTH(0x051) /* RFPLL Control 29 (south) */
205#define B2062_S_RFPLL_CTL30 B43_LP_SOUTH(0x052) /* RFPLL Control 30 (south) */
206#define B2062_S_RFPLL_CTL31 B43_LP_SOUTH(0x053) /* RFPLL Control 31 (south) */
207#define B2062_S_RFPLL_CTL32 B43_LP_SOUTH(0x054) /* RFPLL Control 32 (south) */
208#define B2062_S_RFPLL_CTL33 B43_LP_SOUTH(0x055) /* RFPLL Control 33 (south) */
209#define B2062_S_RFPLL_CTL34 B43_LP_SOUTH(0x056) /* RFPLL Control 34 (south) */
210#define B2062_S_RXG_CNT0 B43_LP_SOUTH(0x057) /* RXG Counter 00 (south) */
211#define B2062_S_RXG_CNT1 B43_LP_SOUTH(0x058) /* RXG Counter 01 (south) */
212#define B2062_S_RXG_CNT2 B43_LP_SOUTH(0x059) /* RXG Counter 02 (south) */
213#define B2062_S_RXG_CNT3 B43_LP_SOUTH(0x05A) /* RXG Counter 03 (south) */
214#define B2062_S_RXG_CNT4 B43_LP_SOUTH(0x05B) /* RXG Counter 04 (south) */
215#define B2062_S_RXG_CNT5 B43_LP_SOUTH(0x05C) /* RXG Counter 05 (south) */
216#define B2062_S_RXG_CNT6 B43_LP_SOUTH(0x05D) /* RXG Counter 06 (south) */
217#define B2062_S_RXG_CNT7 B43_LP_SOUTH(0x05E) /* RXG Counter 07 (south) */
218#define B2062_S_RXG_CNT8 B43_LP_SOUTH(0x05F) /* RXG Counter 08 (south) */
219#define B2062_S_RXG_CNT9 B43_LP_SOUTH(0x060) /* RXG Counter 09 (south) */
220#define B2062_S_RXG_CNT10 B43_LP_SOUTH(0x061) /* RXG Counter 10 (south) */
221#define B2062_S_RXG_CNT11 B43_LP_SOUTH(0x062) /* RXG Counter 11 (south) */
222#define B2062_S_RXG_CNT12 B43_LP_SOUTH(0x063) /* RXG Counter 12 (south) */
223#define B2062_S_RXG_CNT13 B43_LP_SOUTH(0x064) /* RXG Counter 13 (south) */
224#define B2062_S_RXG_CNT14 B43_LP_SOUTH(0x065) /* RXG Counter 14 (south) */
225#define B2062_S_RXG_CNT15 B43_LP_SOUTH(0x066) /* RXG Counter 15 (south) */
226#define B2062_S_RXG_CNT16 B43_LP_SOUTH(0x067) /* RXG Counter 16 (south) */
227#define B2062_S_RXG_CNT17 B43_LP_SOUTH(0x068) /* RXG Counter 17 (south) */
228
229
230
231/*** Broadcom 2063 radio registers ***/
232#define B2063_RADIO_ID_CODE B43_LP_RADIO(0x001) /* Radio ID code */
233#define B2063_COMM1 B43_LP_RADIO(0x000) /* Common 01 */
234#define B2063_COMM2 B43_LP_RADIO(0x002) /* Common 02 */
235#define B2063_COMM3 B43_LP_RADIO(0x003) /* Common 03 */
236#define B2063_COMM4 B43_LP_RADIO(0x004) /* Common 04 */
237#define B2063_COMM5 B43_LP_RADIO(0x005) /* Common 05 */
238#define B2063_COMM6 B43_LP_RADIO(0x006) /* Common 06 */
239#define B2063_COMM7 B43_LP_RADIO(0x007) /* Common 07 */
240#define B2063_COMM8 B43_LP_RADIO(0x008) /* Common 08 */
241#define B2063_COMM9 B43_LP_RADIO(0x009) /* Common 09 */
242#define B2063_COMM10 B43_LP_RADIO(0x00A) /* Common 10 */
243#define B2063_COMM11 B43_LP_RADIO(0x00B) /* Common 11 */
244#define B2063_COMM12 B43_LP_RADIO(0x00C) /* Common 12 */
245#define B2063_COMM13 B43_LP_RADIO(0x00D) /* Common 13 */
246#define B2063_COMM14 B43_LP_RADIO(0x00E) /* Common 14 */
247#define B2063_COMM15 B43_LP_RADIO(0x00F) /* Common 15 */
248#define B2063_COMM16 B43_LP_RADIO(0x010) /* Common 16 */
249#define B2063_COMM17 B43_LP_RADIO(0x011) /* Common 17 */
250#define B2063_COMM18 B43_LP_RADIO(0x012) /* Common 18 */
251#define B2063_COMM19 B43_LP_RADIO(0x013) /* Common 19 */
252#define B2063_COMM20 B43_LP_RADIO(0x014) /* Common 20 */
253#define B2063_COMM21 B43_LP_RADIO(0x015) /* Common 21 */
254#define B2063_COMM22 B43_LP_RADIO(0x016) /* Common 22 */
255#define B2063_COMM23 B43_LP_RADIO(0x017) /* Common 23 */
256#define B2063_COMM24 B43_LP_RADIO(0x018) /* Common 24 */
257#define B2063_PWR_SWITCH_CTL B43_LP_RADIO(0x019) /* POWER SWITCH Control */
258#define B2063_PLL_SP1 B43_LP_RADIO(0x01A) /* PLL SP 1 */
259#define B2063_PLL_SP2 B43_LP_RADIO(0x01B) /* PLL SP 2 */
260#define B2063_LOGEN_SP1 B43_LP_RADIO(0x01C) /* LOGEN SP 1 */
261#define B2063_LOGEN_SP2 B43_LP_RADIO(0x01D) /* LOGEN SP 2 */
262#define B2063_LOGEN_SP3 B43_LP_RADIO(0x01E) /* LOGEN SP 3 */
263#define B2063_LOGEN_SP4 B43_LP_RADIO(0x01F) /* LOGEN SP 4 */
264#define B2063_LOGEN_SP5 B43_LP_RADIO(0x020) /* LOGEN SP 5 */
265#define B2063_G_RX_SP1 B43_LP_RADIO(0x021) /* G RX SP 1 */
266#define B2063_G_RX_SP2 B43_LP_RADIO(0x022) /* G RX SP 2 */
267#define B2063_G_RX_SP3 B43_LP_RADIO(0x023) /* G RX SP 3 */
268#define B2063_G_RX_SP4 B43_LP_RADIO(0x024) /* G RX SP 4 */
269#define B2063_G_RX_SP5 B43_LP_RADIO(0x025) /* G RX SP 5 */
270#define B2063_G_RX_SP6 B43_LP_RADIO(0x026) /* G RX SP 6 */
271#define B2063_G_RX_SP7 B43_LP_RADIO(0x027) /* G RX SP 7 */
272#define B2063_G_RX_SP8 B43_LP_RADIO(0x028) /* G RX SP 8 */
273#define B2063_G_RX_SP9 B43_LP_RADIO(0x029) /* G RX SP 9 */
274#define B2063_G_RX_SP10 B43_LP_RADIO(0x02A) /* G RX SP 10 */
275#define B2063_G_RX_SP11 B43_LP_RADIO(0x02B) /* G RX SP 11 */
276#define B2063_A_RX_SP1 B43_LP_RADIO(0x02C) /* A RX SP 1 */
277#define B2063_A_RX_SP2 B43_LP_RADIO(0x02D) /* A RX SP 2 */
278#define B2063_A_RX_SP3 B43_LP_RADIO(0x02E) /* A RX SP 3 */
279#define B2063_A_RX_SP4 B43_LP_RADIO(0x02F) /* A RX SP 4 */
280#define B2063_A_RX_SP5 B43_LP_RADIO(0x030) /* A RX SP 5 */
281#define B2063_A_RX_SP6 B43_LP_RADIO(0x031) /* A RX SP 6 */
282#define B2063_A_RX_SP7 B43_LP_RADIO(0x032) /* A RX SP 7 */
283#define B2063_RX_BB_SP1 B43_LP_RADIO(0x033) /* RX BB SP 1 */
284#define B2063_RX_BB_SP2 B43_LP_RADIO(0x034) /* RX BB SP 2 */
285#define B2063_RX_BB_SP3 B43_LP_RADIO(0x035) /* RX BB SP 3 */
286#define B2063_RX_BB_SP4 B43_LP_RADIO(0x036) /* RX BB SP 4 */
287#define B2063_RX_BB_SP5 B43_LP_RADIO(0x037) /* RX BB SP 5 */
288#define B2063_RX_BB_SP6 B43_LP_RADIO(0x038) /* RX BB SP 6 */
289#define B2063_RX_BB_SP7 B43_LP_RADIO(0x039) /* RX BB SP 7 */
290#define B2063_RX_BB_SP8 B43_LP_RADIO(0x03A) /* RX BB SP 8 */
291#define B2063_TX_RF_SP1 B43_LP_RADIO(0x03B) /* TX RF SP 1 */
292#define B2063_TX_RF_SP2 B43_LP_RADIO(0x03C) /* TX RF SP 2 */
293#define B2063_TX_RF_SP3 B43_LP_RADIO(0x03D) /* TX RF SP 3 */
294#define B2063_TX_RF_SP4 B43_LP_RADIO(0x03E) /* TX RF SP 4 */
295#define B2063_TX_RF_SP5 B43_LP_RADIO(0x03F) /* TX RF SP 5 */
296#define B2063_TX_RF_SP6 B43_LP_RADIO(0x040) /* TX RF SP 6 */
297#define B2063_TX_RF_SP7 B43_LP_RADIO(0x041) /* TX RF SP 7 */
298#define B2063_TX_RF_SP8 B43_LP_RADIO(0x042) /* TX RF SP 8 */
299#define B2063_TX_RF_SP9 B43_LP_RADIO(0x043) /* TX RF SP 9 */
300#define B2063_TX_RF_SP10 B43_LP_RADIO(0x044) /* TX RF SP 10 */
301#define B2063_TX_RF_SP11 B43_LP_RADIO(0x045) /* TX RF SP 11 */
302#define B2063_TX_RF_SP12 B43_LP_RADIO(0x046) /* TX RF SP 12 */
303#define B2063_TX_RF_SP13 B43_LP_RADIO(0x047) /* TX RF SP 13 */
304#define B2063_TX_RF_SP14 B43_LP_RADIO(0x048) /* TX RF SP 14 */
305#define B2063_TX_RF_SP15 B43_LP_RADIO(0x049) /* TX RF SP 15 */
306#define B2063_TX_RF_SP16 B43_LP_RADIO(0x04A) /* TX RF SP 16 */
307#define B2063_TX_RF_SP17 B43_LP_RADIO(0x04B) /* TX RF SP 17 */
308#define B2063_PA_SP1 B43_LP_RADIO(0x04C) /* PA SP 1 */
309#define B2063_PA_SP2 B43_LP_RADIO(0x04D) /* PA SP 2 */
310#define B2063_PA_SP3 B43_LP_RADIO(0x04E) /* PA SP 3 */
311#define B2063_PA_SP4 B43_LP_RADIO(0x04F) /* PA SP 4 */
312#define B2063_PA_SP5 B43_LP_RADIO(0x050) /* PA SP 5 */
313#define B2063_PA_SP6 B43_LP_RADIO(0x051) /* PA SP 6 */
314#define B2063_PA_SP7 B43_LP_RADIO(0x052) /* PA SP 7 */
315#define B2063_TX_BB_SP1 B43_LP_RADIO(0x053) /* TX BB SP 1 */
316#define B2063_TX_BB_SP2 B43_LP_RADIO(0x054) /* TX BB SP 2 */
317#define B2063_TX_BB_SP3 B43_LP_RADIO(0x055) /* TX BB SP 3 */
318#define B2063_REG_SP1 B43_LP_RADIO(0x056) /* REG SP 1 */
319#define B2063_BANDGAP_CTL1 B43_LP_RADIO(0x057) /* BANDGAP Control 1 */
320#define B2063_BANDGAP_CTL2 B43_LP_RADIO(0x058) /* BANDGAP Control 2 */
321#define B2063_LPO_CTL1 B43_LP_RADIO(0x059) /* LPO Control 1 */
322#define B2063_RC_CALIB_CTL1 B43_LP_RADIO(0x05A) /* RC Calibration Control 1 */
323#define B2063_RC_CALIB_CTL2 B43_LP_RADIO(0x05B) /* RC Calibration Control 2 */
324#define B2063_RC_CALIB_CTL3 B43_LP_RADIO(0x05C) /* RC Calibration Control 3 */
325#define B2063_RC_CALIB_CTL4 B43_LP_RADIO(0x05D) /* RC Calibration Control 4 */
326#define B2063_RC_CALIB_CTL5 B43_LP_RADIO(0x05E) /* RC Calibration Control 5 */
327#define B2063_RC_CALIB_CTL6 B43_LP_RADIO(0x05F) /* RC Calibration Control 6 */
328#define B2063_RC_CALIB_CTL7 B43_LP_RADIO(0x060) /* RC Calibration Control 7 */
329#define B2063_RC_CALIB_CTL8 B43_LP_RADIO(0x061) /* RC Calibration Control 8 */
330#define B2063_RC_CALIB_CTL9 B43_LP_RADIO(0x062) /* RC Calibration Control 9 */
331#define B2063_RC_CALIB_CTL10 B43_LP_RADIO(0x063) /* RC Calibration Control 10 */
332#define B2063_PLL_JTAG_CALNRST B43_LP_RADIO(0x064) /* PLL JTAG CALNRST */
333#define B2063_PLL_JTAG_IN_PLL1 B43_LP_RADIO(0x065) /* PLL JTAG IN PLL 1 */
334#define B2063_PLL_JTAG_IN_PLL2 B43_LP_RADIO(0x066) /* PLL JTAG IN PLL 2 */
335#define B2063_PLL_JTAG_PLL_CP1 B43_LP_RADIO(0x067) /* PLL JTAG PLL CP 1 */
336#define B2063_PLL_JTAG_PLL_CP2 B43_LP_RADIO(0x068) /* PLL JTAG PLL CP 2 */
337#define B2063_PLL_JTAG_PLL_CP3 B43_LP_RADIO(0x069) /* PLL JTAG PLL CP 3 */
338#define B2063_PLL_JTAG_PLL_CP4 B43_LP_RADIO(0x06A) /* PLL JTAG PLL CP 4 */
339#define B2063_PLL_JTAG_PLL_CTL1 B43_LP_RADIO(0x06B) /* PLL JTAG PLL Control 1 */
340#define B2063_PLL_JTAG_PLL_LF1 B43_LP_RADIO(0x06C) /* PLL JTAG PLL LF 1 */
341#define B2063_PLL_JTAG_PLL_LF2 B43_LP_RADIO(0x06D) /* PLL JTAG PLL LF 2 */
342#define B2063_PLL_JTAG_PLL_LF3 B43_LP_RADIO(0x06E) /* PLL JTAG PLL LF 3 */
343#define B2063_PLL_JTAG_PLL_LF4 B43_LP_RADIO(0x06F) /* PLL JTAG PLL LF 4 */
344#define B2063_PLL_JTAG_PLL_SG1 B43_LP_RADIO(0x070) /* PLL JTAG PLL SG 1 */
345#define B2063_PLL_JTAG_PLL_SG2 B43_LP_RADIO(0x071) /* PLL JTAG PLL SG 2 */
346#define B2063_PLL_JTAG_PLL_SG3 B43_LP_RADIO(0x072) /* PLL JTAG PLL SG 3 */
347#define B2063_PLL_JTAG_PLL_SG4 B43_LP_RADIO(0x073) /* PLL JTAG PLL SG 4 */
348#define B2063_PLL_JTAG_PLL_SG5 B43_LP_RADIO(0x074) /* PLL JTAG PLL SG 5 */
349#define B2063_PLL_JTAG_PLL_VCO1 B43_LP_RADIO(0x075) /* PLL JTAG PLL VCO 1 */
350#define B2063_PLL_JTAG_PLL_VCO2 B43_LP_RADIO(0x076) /* PLL JTAG PLL VCO 2 */
351#define B2063_PLL_JTAG_PLL_VCO_CALIB1 B43_LP_RADIO(0x077) /* PLL JTAG PLL VCO Calibration 1 */
352#define B2063_PLL_JTAG_PLL_VCO_CALIB2 B43_LP_RADIO(0x078) /* PLL JTAG PLL VCO Calibration 2 */
353#define B2063_PLL_JTAG_PLL_VCO_CALIB3 B43_LP_RADIO(0x079) /* PLL JTAG PLL VCO Calibration 3 */
354#define B2063_PLL_JTAG_PLL_VCO_CALIB4 B43_LP_RADIO(0x07A) /* PLL JTAG PLL VCO Calibration 4 */
355#define B2063_PLL_JTAG_PLL_VCO_CALIB5 B43_LP_RADIO(0x07B) /* PLL JTAG PLL VCO Calibration 5 */
356#define B2063_PLL_JTAG_PLL_VCO_CALIB6 B43_LP_RADIO(0x07C) /* PLL JTAG PLL VCO Calibration 6 */
357#define B2063_PLL_JTAG_PLL_VCO_CALIB7 B43_LP_RADIO(0x07D) /* PLL JTAG PLL VCO Calibration 7 */
358#define B2063_PLL_JTAG_PLL_VCO_CALIB8 B43_LP_RADIO(0x07E) /* PLL JTAG PLL VCO Calibration 8 */
359#define B2063_PLL_JTAG_PLL_VCO_CALIB9 B43_LP_RADIO(0x07F) /* PLL JTAG PLL VCO Calibration 9 */
360#define B2063_PLL_JTAG_PLL_VCO_CALIB10 B43_LP_RADIO(0x080) /* PLL JTAG PLL VCO Calibration 10 */
361#define B2063_PLL_JTAG_PLL_XTAL_12 B43_LP_RADIO(0x081) /* PLL JTAG PLL XTAL 1 2 */
362#define B2063_PLL_JTAG_PLL_XTAL3 B43_LP_RADIO(0x082) /* PLL JTAG PLL XTAL 3 */
363#define B2063_LOGEN_ACL1 B43_LP_RADIO(0x083) /* LOGEN ACL 1 */
364#define B2063_LOGEN_ACL2 B43_LP_RADIO(0x084) /* LOGEN ACL 2 */
365#define B2063_LOGEN_ACL3 B43_LP_RADIO(0x085) /* LOGEN ACL 3 */
366#define B2063_LOGEN_ACL4 B43_LP_RADIO(0x086) /* LOGEN ACL 4 */
367#define B2063_LOGEN_ACL5 B43_LP_RADIO(0x087) /* LOGEN ACL 5 */
368#define B2063_LO_CALIB_INPUTS B43_LP_RADIO(0x088) /* LO Calibration INPUTS */
369#define B2063_LO_CALIB_CTL1 B43_LP_RADIO(0x089) /* LO Calibration Control 1 */
370#define B2063_LO_CALIB_CTL2 B43_LP_RADIO(0x08A) /* LO Calibration Control 2 */
371#define B2063_LO_CALIB_CTL3 B43_LP_RADIO(0x08B) /* LO Calibration Control 3 */
372#define B2063_LO_CALIB_WAITCNT B43_LP_RADIO(0x08C) /* LO Calibration WAITCNT */
373#define B2063_LO_CALIB_OVR1 B43_LP_RADIO(0x08D) /* LO Calibration OVR 1 */
374#define B2063_LO_CALIB_OVR2 B43_LP_RADIO(0x08E) /* LO Calibration OVR 2 */
375#define B2063_LO_CALIB_OVAL1 B43_LP_RADIO(0x08F) /* LO Calibration OVAL 1 */
376#define B2063_LO_CALIB_OVAL2 B43_LP_RADIO(0x090) /* LO Calibration OVAL 2 */
377#define B2063_LO_CALIB_OVAL3 B43_LP_RADIO(0x091) /* LO Calibration OVAL 3 */
378#define B2063_LO_CALIB_OVAL4 B43_LP_RADIO(0x092) /* LO Calibration OVAL 4 */
379#define B2063_LO_CALIB_OVAL5 B43_LP_RADIO(0x093) /* LO Calibration OVAL 5 */
380#define B2063_LO_CALIB_OVAL6 B43_LP_RADIO(0x094) /* LO Calibration OVAL 6 */
381#define B2063_LO_CALIB_OVAL7 B43_LP_RADIO(0x095) /* LO Calibration OVAL 7 */
382#define B2063_LO_CALIB_CALVLD1 B43_LP_RADIO(0x096) /* LO Calibration CALVLD 1 */
383#define B2063_LO_CALIB_CALVLD2 B43_LP_RADIO(0x097) /* LO Calibration CALVLD 2 */
384#define B2063_LO_CALIB_CVAL1 B43_LP_RADIO(0x098) /* LO Calibration CVAL 1 */
385#define B2063_LO_CALIB_CVAL2 B43_LP_RADIO(0x099) /* LO Calibration CVAL 2 */
386#define B2063_LO_CALIB_CVAL3 B43_LP_RADIO(0x09A) /* LO Calibration CVAL 3 */
387#define B2063_LO_CALIB_CVAL4 B43_LP_RADIO(0x09B) /* LO Calibration CVAL 4 */
388#define B2063_LO_CALIB_CVAL5 B43_LP_RADIO(0x09C) /* LO Calibration CVAL 5 */
389#define B2063_LO_CALIB_CVAL6 B43_LP_RADIO(0x09D) /* LO Calibration CVAL 6 */
390#define B2063_LO_CALIB_CVAL7 B43_LP_RADIO(0x09E) /* LO Calibration CVAL 7 */
391#define B2063_LOGEN_CALIB_EN B43_LP_RADIO(0x09F) /* LOGEN Calibration EN */
392#define B2063_LOGEN_PEAKDET1 B43_LP_RADIO(0x0A0) /* LOGEN PEAKDET 1 */
393#define B2063_LOGEN_RCCR1 B43_LP_RADIO(0x0A1) /* LOGEN RCCR 1 */
394#define B2063_LOGEN_VCOBUF1 B43_LP_RADIO(0x0A2) /* LOGEN VCOBUF 1 */
395#define B2063_LOGEN_MIXER1 B43_LP_RADIO(0x0A3) /* LOGEN MIXER 1 */
396#define B2063_LOGEN_MIXER2 B43_LP_RADIO(0x0A4) /* LOGEN MIXER 2 */
397#define B2063_LOGEN_BUF1 B43_LP_RADIO(0x0A5) /* LOGEN BUF 1 */
398#define B2063_LOGEN_BUF2 B43_LP_RADIO(0x0A6) /* LOGEN BUF 2 */
399#define B2063_LOGEN_DIV1 B43_LP_RADIO(0x0A7) /* LOGEN DIV 1 */
400#define B2063_LOGEN_DIV2 B43_LP_RADIO(0x0A8) /* LOGEN DIV 2 */
401#define B2063_LOGEN_DIV3 B43_LP_RADIO(0x0A9) /* LOGEN DIV 3 */
402#define B2063_LOGEN_CBUFRX1 B43_LP_RADIO(0x0AA) /* LOGEN CBUFRX 1 */
403#define B2063_LOGEN_CBUFRX2 B43_LP_RADIO(0x0AB) /* LOGEN CBUFRX 2 */
404#define B2063_LOGEN_CBUFTX1 B43_LP_RADIO(0x0AC) /* LOGEN CBUFTX 1 */
405#define B2063_LOGEN_CBUFTX2 B43_LP_RADIO(0x0AD) /* LOGEN CBUFTX 2 */
406#define B2063_LOGEN_IDAC1 B43_LP_RADIO(0x0AE) /* LOGEN IDAC 1 */
407#define B2063_LOGEN_SPARE1 B43_LP_RADIO(0x0AF) /* LOGEN SPARE 1 */
408#define B2063_LOGEN_SPARE2 B43_LP_RADIO(0x0B0) /* LOGEN SPARE 2 */
409#define B2063_LOGEN_SPARE3 B43_LP_RADIO(0x0B1) /* LOGEN SPARE 3 */
410#define B2063_G_RX_1ST1 B43_LP_RADIO(0x0B2) /* G RX 1ST 1 */
411#define B2063_G_RX_1ST2 B43_LP_RADIO(0x0B3) /* G RX 1ST 2 */
412#define B2063_G_RX_1ST3 B43_LP_RADIO(0x0B4) /* G RX 1ST 3 */
413#define B2063_G_RX_2ND1 B43_LP_RADIO(0x0B5) /* G RX 2ND 1 */
414#define B2063_G_RX_2ND2 B43_LP_RADIO(0x0B6) /* G RX 2ND 2 */
415#define B2063_G_RX_2ND3 B43_LP_RADIO(0x0B7) /* G RX 2ND 3 */
416#define B2063_G_RX_2ND4 B43_LP_RADIO(0x0B8) /* G RX 2ND 4 */
417#define B2063_G_RX_2ND5 B43_LP_RADIO(0x0B9) /* G RX 2ND 5 */
418#define B2063_G_RX_2ND6 B43_LP_RADIO(0x0BA) /* G RX 2ND 6 */
419#define B2063_G_RX_2ND7 B43_LP_RADIO(0x0BB) /* G RX 2ND 7 */
420#define B2063_G_RX_2ND8 B43_LP_RADIO(0x0BC) /* G RX 2ND 8 */
421#define B2063_G_RX_PS1 B43_LP_RADIO(0x0BD) /* G RX PS 1 */
422#define B2063_G_RX_PS2 B43_LP_RADIO(0x0BE) /* G RX PS 2 */
423#define B2063_G_RX_PS3 B43_LP_RADIO(0x0BF) /* G RX PS 3 */
424#define B2063_G_RX_PS4 B43_LP_RADIO(0x0C0) /* G RX PS 4 */
425#define B2063_G_RX_PS5 B43_LP_RADIO(0x0C1) /* G RX PS 5 */
426#define B2063_G_RX_MIX1 B43_LP_RADIO(0x0C2) /* G RX MIX 1 */
427#define B2063_G_RX_MIX2 B43_LP_RADIO(0x0C3) /* G RX MIX 2 */
428#define B2063_G_RX_MIX3 B43_LP_RADIO(0x0C4) /* G RX MIX 3 */
429#define B2063_G_RX_MIX4 B43_LP_RADIO(0x0C5) /* G RX MIX 4 */
430#define B2063_G_RX_MIX5 B43_LP_RADIO(0x0C6) /* G RX MIX 5 */
431#define B2063_G_RX_MIX6 B43_LP_RADIO(0x0C7) /* G RX MIX 6 */
432#define B2063_G_RX_MIX7 B43_LP_RADIO(0x0C8) /* G RX MIX 7 */
433#define B2063_G_RX_MIX8 B43_LP_RADIO(0x0C9) /* G RX MIX 8 */
434#define B2063_G_RX_PDET1 B43_LP_RADIO(0x0CA) /* G RX PDET 1 */
435#define B2063_G_RX_SPARES1 B43_LP_RADIO(0x0CB) /* G RX SPARES 1 */
436#define B2063_G_RX_SPARES2 B43_LP_RADIO(0x0CC) /* G RX SPARES 2 */
437#define B2063_G_RX_SPARES3 B43_LP_RADIO(0x0CD) /* G RX SPARES 3 */
438#define B2063_A_RX_1ST1 B43_LP_RADIO(0x0CE) /* A RX 1ST 1 */
439#define B2063_A_RX_1ST2 B43_LP_RADIO(0x0CF) /* A RX 1ST 2 */
440#define B2063_A_RX_1ST3 B43_LP_RADIO(0x0D0) /* A RX 1ST 3 */
441#define B2063_A_RX_1ST4 B43_LP_RADIO(0x0D1) /* A RX 1ST 4 */
442#define B2063_A_RX_1ST5 B43_LP_RADIO(0x0D2) /* A RX 1ST 5 */
443#define B2063_A_RX_2ND1 B43_LP_RADIO(0x0D3) /* A RX 2ND 1 */
444#define B2063_A_RX_2ND2 B43_LP_RADIO(0x0D4) /* A RX 2ND 2 */
445#define B2063_A_RX_2ND3 B43_LP_RADIO(0x0D5) /* A RX 2ND 3 */
446#define B2063_A_RX_2ND4 B43_LP_RADIO(0x0D6) /* A RX 2ND 4 */
447#define B2063_A_RX_2ND5 B43_LP_RADIO(0x0D7) /* A RX 2ND 5 */
448#define B2063_A_RX_2ND6 B43_LP_RADIO(0x0D8) /* A RX 2ND 6 */
449#define B2063_A_RX_2ND7 B43_LP_RADIO(0x0D9) /* A RX 2ND 7 */
450#define B2063_A_RX_PS1 B43_LP_RADIO(0x0DA) /* A RX PS 1 */
451#define B2063_A_RX_PS2 B43_LP_RADIO(0x0DB) /* A RX PS 2 */
452#define B2063_A_RX_PS3 B43_LP_RADIO(0x0DC) /* A RX PS 3 */
453#define B2063_A_RX_PS4 B43_LP_RADIO(0x0DD) /* A RX PS 4 */
454#define B2063_A_RX_PS5 B43_LP_RADIO(0x0DE) /* A RX PS 5 */
455#define B2063_A_RX_PS6 B43_LP_RADIO(0x0DF) /* A RX PS 6 */
456#define B2063_A_RX_MIX1 B43_LP_RADIO(0x0E0) /* A RX MIX 1 */
457#define B2063_A_RX_MIX2 B43_LP_RADIO(0x0E1) /* A RX MIX 2 */
458#define B2063_A_RX_MIX3 B43_LP_RADIO(0x0E2) /* A RX MIX 3 */
459#define B2063_A_RX_MIX4 B43_LP_RADIO(0x0E3) /* A RX MIX 4 */
460#define B2063_A_RX_MIX5 B43_LP_RADIO(0x0E4) /* A RX MIX 5 */
461#define B2063_A_RX_MIX6 B43_LP_RADIO(0x0E5) /* A RX MIX 6 */
462#define B2063_A_RX_MIX7 B43_LP_RADIO(0x0E6) /* A RX MIX 7 */
463#define B2063_A_RX_MIX8 B43_LP_RADIO(0x0E7) /* A RX MIX 8 */
464#define B2063_A_RX_PWRDET1 B43_LP_RADIO(0x0E8) /* A RX PWRDET 1 */
465#define B2063_A_RX_SPARE1 B43_LP_RADIO(0x0E9) /* A RX SPARE 1 */
466#define B2063_A_RX_SPARE2 B43_LP_RADIO(0x0EA) /* A RX SPARE 2 */
467#define B2063_A_RX_SPARE3 B43_LP_RADIO(0x0EB) /* A RX SPARE 3 */
468#define B2063_RX_TIA_CTL1 B43_LP_RADIO(0x0EC) /* RX TIA Control 1 */
469#define B2063_RX_TIA_CTL2 B43_LP_RADIO(0x0ED) /* RX TIA Control 2 */
470#define B2063_RX_TIA_CTL3 B43_LP_RADIO(0x0EE) /* RX TIA Control 3 */
471#define B2063_RX_TIA_CTL4 B43_LP_RADIO(0x0EF) /* RX TIA Control 4 */
472#define B2063_RX_TIA_CTL5 B43_LP_RADIO(0x0F0) /* RX TIA Control 5 */
473#define B2063_RX_TIA_CTL6 B43_LP_RADIO(0x0F1) /* RX TIA Control 6 */
474#define B2063_RX_BB_CTL1 B43_LP_RADIO(0x0F2) /* RX BB Control 1 */
475#define B2063_RX_BB_CTL2 B43_LP_RADIO(0x0F3) /* RX BB Control 2 */
476#define B2063_RX_BB_CTL3 B43_LP_RADIO(0x0F4) /* RX BB Control 3 */
477#define B2063_RX_BB_CTL4 B43_LP_RADIO(0x0F5) /* RX BB Control 4 */
478#define B2063_RX_BB_CTL5 B43_LP_RADIO(0x0F6) /* RX BB Control 5 */
479#define B2063_RX_BB_CTL6 B43_LP_RADIO(0x0F7) /* RX BB Control 6 */
480#define B2063_RX_BB_CTL7 B43_LP_RADIO(0x0F8) /* RX BB Control 7 */
481#define B2063_RX_BB_CTL8 B43_LP_RADIO(0x0F9) /* RX BB Control 8 */
482#define B2063_RX_BB_CTL9 B43_LP_RADIO(0x0FA) /* RX BB Control 9 */
483#define B2063_TX_RF_CTL1 B43_LP_RADIO(0x0FB) /* TX RF Control 1 */
484#define B2063_TX_RF_IDAC_LO_RF_I B43_LP_RADIO(0x0FC) /* TX RF IDAC LO RF I */
485#define B2063_TX_RF_IDAC_LO_RF_Q B43_LP_RADIO(0x0FD) /* TX RF IDAC LO RF Q */
486#define B2063_TX_RF_IDAC_LO_BB_I B43_LP_RADIO(0x0FE) /* TX RF IDAC LO BB I */
487#define B2063_TX_RF_IDAC_LO_BB_Q B43_LP_RADIO(0x0FF) /* TX RF IDAC LO BB Q */
488#define B2063_TX_RF_CTL2 B43_LP_RADIO(0x100) /* TX RF Control 2 */
489#define B2063_TX_RF_CTL3 B43_LP_RADIO(0x101) /* TX RF Control 3 */
490#define B2063_TX_RF_CTL4 B43_LP_RADIO(0x102) /* TX RF Control 4 */
491#define B2063_TX_RF_CTL5 B43_LP_RADIO(0x103) /* TX RF Control 5 */
492#define B2063_TX_RF_CTL6 B43_LP_RADIO(0x104) /* TX RF Control 6 */
493#define B2063_TX_RF_CTL7 B43_LP_RADIO(0x105) /* TX RF Control 7 */
494#define B2063_TX_RF_CTL8 B43_LP_RADIO(0x106) /* TX RF Control 8 */
495#define B2063_TX_RF_CTL9 B43_LP_RADIO(0x107) /* TX RF Control 9 */
496#define B2063_TX_RF_CTL10 B43_LP_RADIO(0x108) /* TX RF Control 10 */
497#define B2063_TX_RF_CTL14 B43_LP_RADIO(0x109) /* TX RF Control 14 */
498#define B2063_TX_RF_CTL15 B43_LP_RADIO(0x10A) /* TX RF Control 15 */
499#define B2063_PA_CTL1 B43_LP_RADIO(0x10B) /* PA Control 1 */
500#define B2063_PA_CTL2 B43_LP_RADIO(0x10C) /* PA Control 2 */
501#define B2063_PA_CTL3 B43_LP_RADIO(0x10D) /* PA Control 3 */
502#define B2063_PA_CTL4 B43_LP_RADIO(0x10E) /* PA Control 4 */
503#define B2063_PA_CTL5 B43_LP_RADIO(0x10F) /* PA Control 5 */
504#define B2063_PA_CTL6 B43_LP_RADIO(0x110) /* PA Control 6 */
505#define B2063_PA_CTL7 B43_LP_RADIO(0x111) /* PA Control 7 */
506#define B2063_PA_CTL8 B43_LP_RADIO(0x112) /* PA Control 8 */
507#define B2063_PA_CTL9 B43_LP_RADIO(0x113) /* PA Control 9 */
508#define B2063_PA_CTL10 B43_LP_RADIO(0x114) /* PA Control 10 */
509#define B2063_PA_CTL11 B43_LP_RADIO(0x115) /* PA Control 11 */
510#define B2063_PA_CTL12 B43_LP_RADIO(0x116) /* PA Control 12 */
511#define B2063_PA_CTL13 B43_LP_RADIO(0x117) /* PA Control 13 */
512#define B2063_TX_BB_CTL1 B43_LP_RADIO(0x118) /* TX BB Control 1 */
513#define B2063_TX_BB_CTL2 B43_LP_RADIO(0x119) /* TX BB Control 2 */
514#define B2063_TX_BB_CTL3 B43_LP_RADIO(0x11A) /* TX BB Control 3 */
515#define B2063_TX_BB_CTL4 B43_LP_RADIO(0x11B) /* TX BB Control 4 */
516#define B2063_GPIO_CTL1 B43_LP_RADIO(0x11C) /* GPIO Control 1 */
517#define B2063_VREG_CTL1 B43_LP_RADIO(0x11D) /* VREG Control 1 */
518#define B2063_AMUX_CTL1 B43_LP_RADIO(0x11E) /* AMUX Control 1 */
519#define B2063_IQ_CALIB_GVAR B43_LP_RADIO(0x11F) /* IQ Calibration GVAR */
520#define B2063_IQ_CALIB_CTL1 B43_LP_RADIO(0x120) /* IQ Calibration Control 1 */
521#define B2063_IQ_CALIB_CTL2 B43_LP_RADIO(0x121) /* IQ Calibration Control 2 */
522#define B2063_TEMPSENSE_CTL1 B43_LP_RADIO(0x122) /* TEMPSENSE Control 1 */
523#define B2063_TEMPSENSE_CTL2 B43_LP_RADIO(0x123) /* TEMPSENSE Control 2 */
524#define B2063_TX_RX_LOOPBACK1 B43_LP_RADIO(0x124) /* TX/RX LOOPBACK 1 */
525#define B2063_TX_RX_LOOPBACK2 B43_LP_RADIO(0x125) /* TX/RX LOOPBACK 2 */
526#define B2063_EXT_TSSI_CTL1 B43_LP_RADIO(0x126) /* EXT TSSI Control 1 */
527#define B2063_EXT_TSSI_CTL2 B43_LP_RADIO(0x127) /* EXT TSSI Control 2 */
528#define B2063_AFE_CTL B43_LP_RADIO(0x128) /* AFE Control */
529
530
531
532struct b43_phy_lp {
533 //TODO
534};
535
536
537struct b43_phy_operations;
538extern const struct b43_phy_operations b43_phyops_lp;
539
540#endif /* LINUX_B43_PHY_LP_H_ */
diff --git a/drivers/net/wireless/b43/nphy.c b/drivers/net/wireless/b43/phy_n.c
index 4cfeab8560f6..8bcfda5f3f07 100644
--- a/drivers/net/wireless/b43/nphy.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -26,7 +26,7 @@
26#include <linux/types.h> 26#include <linux/types.h>
27 27
28#include "b43.h" 28#include "b43.h"
29#include "nphy.h" 29#include "phy_n.h"
30#include "tables_nphy.h" 30#include "tables_nphy.h"
31 31
32 32
@@ -499,35 +499,31 @@ static int b43_nphy_op_allocate(struct b43_wldev *dev)
499 return -ENOMEM; 499 return -ENOMEM;
500 dev->phy.n = nphy; 500 dev->phy.n = nphy;
501 501
502 //TODO init struct b43_phy_n
503
504 return 0; 502 return 0;
505} 503}
506 504
507static int b43_nphy_op_init(struct b43_wldev *dev) 505static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
508{ 506{
509 struct b43_phy_n *nphy = dev->phy.n; 507 struct b43_phy *phy = &dev->phy;
510 int err; 508 struct b43_phy_n *nphy = phy->n;
511 509
512 err = b43_phy_initn(dev); 510 memset(nphy, 0, sizeof(*nphy));
513 if (err)
514 return err;
515 nphy->initialised = 1;
516 511
517 return 0; 512 //TODO init struct b43_phy_n
518} 513}
519 514
520static void b43_nphy_op_exit(struct b43_wldev *dev) 515static void b43_nphy_op_free(struct b43_wldev *dev)
521{ 516{
522 struct b43_phy_n *nphy = dev->phy.n; 517 struct b43_phy *phy = &dev->phy;
518 struct b43_phy_n *nphy = phy->n;
523 519
524 if (nphy->initialised) {
525 //TODO
526 nphy->initialised = 0;
527 }
528 //TODO
529 kfree(nphy); 520 kfree(nphy);
530 dev->phy.n = NULL; 521 phy->n = NULL;
522}
523
524static int b43_nphy_op_init(struct b43_wldev *dev)
525{
526 return b43_phy_initn(dev);
531} 527}
532 528
533static inline void check_phyreg(struct b43_wldev *dev, u16 offset) 529static inline void check_phyreg(struct b43_wldev *dev, u16 offset)
@@ -587,6 +583,12 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
587{//TODO 583{//TODO
588} 584}
589 585
586static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
587{
588 b43_phy_write(dev, B43_NPHY_AFECTL_OVER,
589 on ? 0 : 0x7FFF);
590}
591
590static int b43_nphy_op_switch_channel(struct b43_wldev *dev, 592static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
591 unsigned int new_channel) 593 unsigned int new_channel)
592{ 594{
@@ -610,13 +612,15 @@ static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
610 612
611const struct b43_phy_operations b43_phyops_n = { 613const struct b43_phy_operations b43_phyops_n = {
612 .allocate = b43_nphy_op_allocate, 614 .allocate = b43_nphy_op_allocate,
615 .free = b43_nphy_op_free,
616 .prepare_structs = b43_nphy_op_prepare_structs,
613 .init = b43_nphy_op_init, 617 .init = b43_nphy_op_init,
614 .exit = b43_nphy_op_exit,
615 .phy_read = b43_nphy_op_read, 618 .phy_read = b43_nphy_op_read,
616 .phy_write = b43_nphy_op_write, 619 .phy_write = b43_nphy_op_write,
617 .radio_read = b43_nphy_op_radio_read, 620 .radio_read = b43_nphy_op_radio_read,
618 .radio_write = b43_nphy_op_radio_write, 621 .radio_write = b43_nphy_op_radio_write,
619 .software_rfkill = b43_nphy_op_software_rfkill, 622 .software_rfkill = b43_nphy_op_software_rfkill,
623 .switch_analog = b43_nphy_op_switch_analog,
620 .switch_channel = b43_nphy_op_switch_channel, 624 .switch_channel = b43_nphy_op_switch_channel,
621 .get_default_chan = b43_nphy_op_get_default_chan, 625 .get_default_chan = b43_nphy_op_get_default_chan,
622 .recalc_txpower = b43_nphy_op_recalc_txpower, 626 .recalc_txpower = b43_nphy_op_recalc_txpower,
diff --git a/drivers/net/wireless/b43/nphy.h b/drivers/net/wireless/b43/phy_n.h
index 3d1f65ed2012..1749aef4147d 100644
--- a/drivers/net/wireless/b43/nphy.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -920,8 +920,6 @@
920struct b43_wldev; 920struct b43_wldev;
921 921
922struct b43_phy_n { 922struct b43_phy_n {
923 bool initialised;
924
925 //TODO lots of missing stuff 923 //TODO lots of missing stuff
926}; 924};
927 925
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 1de2c2e2e14c..4e2336315545 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -25,7 +25,7 @@
25#include "b43.h" 25#include "b43.h"
26#include "tables_nphy.h" 26#include "tables_nphy.h"
27#include "phy_common.h" 27#include "phy_common.h"
28#include "nphy.h" 28#include "phy_n.h"
29 29
30 30
31struct b2055_inittab_entry { 31struct b2055_inittab_entry {
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 1cb77db5c292..68f63f5093af 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3704,6 +3704,11 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
3704 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 3704 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
3705 IEEE80211_HW_SIGNAL_DBM | 3705 IEEE80211_HW_SIGNAL_DBM |
3706 IEEE80211_HW_NOISE_DBM; 3706 IEEE80211_HW_NOISE_DBM;
3707 hw->wiphy->interface_modes =
3708 BIT(NL80211_IFTYPE_AP) |
3709 BIT(NL80211_IFTYPE_STATION) |
3710 BIT(NL80211_IFTYPE_WDS) |
3711 BIT(NL80211_IFTYPE_ADHOC);
3707 hw->queues = 1; /* FIXME: hardware has more queues */ 3712 hw->queues = 1; /* FIXME: hardware has more queues */
3708 SET_IEEE80211_DEV(hw, dev->dev); 3713 SET_IEEE80211_DEV(hw, dev->dev);
3709 if (is_valid_ether_addr(sprom->et1mac)) 3714 if (is_valid_ether_addr(sprom->et1mac))
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
index 0b9475114618..b3fe48de3ae7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
@@ -59,7 +59,7 @@
59 * 59 *
60 */ 60 */
61 61
62#define _iwl3945_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs)) 62#define _iwl3945_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs))
63#ifdef CONFIG_IWL3945_DEBUG 63#ifdef CONFIG_IWL3945_DEBUG
64static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv, 64static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv,
65 u32 ofs, u32 val) 65 u32 ofs, u32 val)
@@ -73,14 +73,14 @@ static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *
73#define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val) 73#define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val)
74#endif 74#endif
75 75
76#define _iwl3945_read32(priv, ofs) readl((priv)->hw_base + (ofs)) 76#define _iwl3945_read32(priv, ofs) ioread32((priv)->hw_base + (ofs))
77#ifdef CONFIG_IWL3945_DEBUG 77#ifdef CONFIG_IWL3945_DEBUG
78static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs) 78static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs)
79{ 79{
80 IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); 80 IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
81 return _iwl3945_read32(priv, ofs); 81 return _iwl3945_read32(priv, ofs);
82} 82}
83#define iwl3945_read32(priv, ofs) __iwl3945_read32(__FILE__, __LINE__, priv, ofs) 83#define iwl3945_read32(priv, ofs)__iwl3945_read32(__FILE__, __LINE__, priv, ofs)
84#else 84#else
85#define iwl3945_read32(p, o) _iwl3945_read32(p, o) 85#define iwl3945_read32(p, o) _iwl3945_read32(p, o)
86#endif 86#endif
@@ -153,28 +153,10 @@ static inline void __iwl3945_clear_bit(const char *f, u32 l,
153static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv) 153static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv)
154{ 154{
155 int ret; 155 int ret;
156 u32 gp_ctl;
157
158#ifdef CONFIG_IWL3945_DEBUG 156#ifdef CONFIG_IWL3945_DEBUG
159 if (atomic_read(&priv->restrict_refcnt)) 157 if (atomic_read(&priv->restrict_refcnt))
160 return 0; 158 return 0;
161#endif 159#endif
162 if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
163 test_bit(STATUS_RF_KILL_SW, &priv->status)) {
164 IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
165 "wakes up NIC\n");
166
167 /* 10 msec allows time for NIC to complete its data save */
168 gp_ctl = _iwl3945_read32(priv, CSR_GP_CNTRL);
169 if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
170 IWL_DEBUG_RF_KILL("Wait for complete power-down, "
171 "gpctl = 0x%08x\n", gp_ctl);
172 mdelay(10);
173 } else
174 IWL_DEBUG_RF_KILL("power-down complete, "
175 "gpctl = 0x%08x\n", gp_ctl);
176 }
177
178 /* this bit wakes up the NIC */ 160 /* this bit wakes up the NIC */
179 _iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 161 _iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
180 ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL, 162 ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8dc26adc1975..1377c8190ecb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -688,87 +688,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
688 688
689 switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) { 689 switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
690 case IEEE80211_FTYPE_MGMT: 690 case IEEE80211_FTYPE_MGMT:
691 switch (le16_to_cpu(header->frame_control) &
692 IEEE80211_FCTL_STYPE) {
693 case IEEE80211_STYPE_PROBE_RESP:
694 case IEEE80211_STYPE_BEACON:{
695 /* If this is a beacon or probe response for
696 * our network then cache the beacon
697 * timestamp */
698 if ((((priv->iw_mode == IEEE80211_IF_TYPE_STA)
699 && !compare_ether_addr(header->addr2,
700 priv->bssid)) ||
701 ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
702 && !compare_ether_addr(header->addr3,
703 priv->bssid)))) {
704 struct ieee80211_mgmt *mgmt =
705 (struct ieee80211_mgmt *)header;
706 __le32 *pos;
707 pos = (__le32 *)&mgmt->u.beacon.
708 timestamp;
709 priv->timestamp0 = le32_to_cpu(pos[0]);
710 priv->timestamp1 = le32_to_cpu(pos[1]);
711 priv->beacon_int = le16_to_cpu(
712 mgmt->u.beacon.beacon_int);
713 if (priv->call_post_assoc_from_beacon &&
714 (priv->iw_mode ==
715 IEEE80211_IF_TYPE_STA))
716 queue_work(priv->workqueue,
717 &priv->post_associate.work);
718
719 priv->call_post_assoc_from_beacon = 0;
720 }
721
722 break;
723 }
724
725 case IEEE80211_STYPE_ACTION:
726 /* TODO: Parse 802.11h frames for CSA... */
727 break;
728
729 /*
730 * TODO: Use the new callback function from
731 * mac80211 instead of sniffing these packets.
732 */
733 case IEEE80211_STYPE_ASSOC_RESP:
734 case IEEE80211_STYPE_REASSOC_RESP:{
735 struct ieee80211_mgmt *mgnt =
736 (struct ieee80211_mgmt *)header;
737
738 /* We have just associated, give some
739 * time for the 4-way handshake if
740 * any. Don't start scan too early. */
741 priv->next_scan_jiffies = jiffies +
742 IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
743
744 priv->assoc_id = (~((1 << 15) | (1 << 14)) &
745 le16_to_cpu(mgnt->u.
746 assoc_resp.aid));
747 priv->assoc_capability =
748 le16_to_cpu(mgnt->u.assoc_resp.capab_info);
749 if (priv->beacon_int)
750 queue_work(priv->workqueue,
751 &priv->post_associate.work);
752 else
753 priv->call_post_assoc_from_beacon = 1;
754 break;
755 }
756
757 case IEEE80211_STYPE_PROBE_REQ:{
758 DECLARE_MAC_BUF(mac1);
759 DECLARE_MAC_BUF(mac2);
760 DECLARE_MAC_BUF(mac3);
761 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
762 IWL_DEBUG_DROP
763 ("Dropping (non network): %s"
764 ", %s, %s\n",
765 print_mac(mac1, header->addr1),
766 print_mac(mac2, header->addr2),
767 print_mac(mac3, header->addr3));
768 return;
769 }
770 }
771
772 case IEEE80211_FTYPE_DATA: 691 case IEEE80211_FTYPE_DATA:
773 /* fall through */ 692 /* fall through */
774 default: 693 default:
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 4dd3f0dbe07b..9bbbc9d7c0e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -894,7 +894,6 @@ struct iwl3945_priv {
894 struct delayed_work thermal_periodic; 894 struct delayed_work thermal_periodic;
895 struct delayed_work gather_stats; 895 struct delayed_work gather_stats;
896 struct delayed_work scan_check; 896 struct delayed_work scan_check;
897 struct delayed_work post_associate;
898 897
899#define IWL_DEFAULT_TX_POWER 0x0F 898#define IWL_DEFAULT_TX_POWER 0x0F
900 s8 user_txpower_limit; 899 s8 user_txpower_limit;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index fce950f4163c..f4793a609443 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -98,16 +98,17 @@
98#define IWL_RSSI_OFFSET 44 98#define IWL_RSSI_OFFSET 44
99 99
100 100
101#include "iwl-commands.h"
102 101
103/* PCI registers */ 102/* PCI registers */
104#define PCI_LINK_CTRL 0x0F0 /* 1 byte */ 103#define PCI_CFG_RETRY_TIMEOUT 0x041
105#define PCI_POWER_SOURCE 0x0C8 104#define PCI_CFG_POWER_SOURCE 0x0C8
106#define PCI_REG_WUM8 0x0E8 105#define PCI_REG_WUM8 0x0E8
106#define PCI_CFG_LINK_CTRL 0x0F0
107 107
108/* PCI register values */ 108/* PCI register values */
109#define PCI_LINK_VAL_L0S_EN 0x01 109#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
110#define PCI_LINK_VAL_L1_EN 0x02 110#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
111#define PCI_CFG_CMD_REG_INT_DIS_MSK 0x04
111#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) 112#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
112 113
113#define TFD_QUEUE_SIZE_MAX (256) 114#define TFD_QUEUE_SIZE_MAX (256)
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index e2581229d8b2..46e076af8f7e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -399,7 +399,7 @@ static void iwl4965_nic_config(struct iwl_priv *priv)
399 unsigned long flags; 399 unsigned long flags;
400 u32 val; 400 u32 val;
401 u16 radio_cfg; 401 u16 radio_cfg;
402 u8 val_link; 402 u16 link;
403 403
404 spin_lock_irqsave(&priv->lock, flags); 404 spin_lock_irqsave(&priv->lock, flags);
405 405
@@ -410,10 +410,10 @@ static void iwl4965_nic_config(struct iwl_priv *priv)
410 val & ~(1 << 11)); 410 val & ~(1 << 11));
411 } 411 }
412 412
413 pci_read_config_byte(priv->pci_dev, PCI_LINK_CTRL, &val_link); 413 pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
414 414
415 /* L1 is enabled by BIOS */ 415 /* L1 is enabled by BIOS */
416 if ((val_link & PCI_LINK_VAL_L1_EN) == PCI_LINK_VAL_L1_EN) 416 if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
417 /* diable L0S disabled L1A enabled */ 417 /* diable L0S disabled L1A enabled */
418 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); 418 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
419 else 419 else
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 17d4f31c5934..c479ee211c5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -129,6 +129,13 @@ struct iwl5000_shared {
129 __le32 padding2; 129 __le32 padding2;
130} __attribute__ ((packed)); 130} __attribute__ ((packed));
131 131
132/* calibrations defined for 5000 */
133/* defines the order in which results should be sent to the runtime uCode */
134enum iwl5000_calib {
135 IWL5000_CALIB_LO,
136 IWL5000_CALIB_TX_IQ,
137 IWL5000_CALIB_TX_IQ_PERD,
138};
132 139
133#endif /* __iwl_5000_hw_h__ */ 140#endif /* __iwl_5000_hw_h__ */
134 141
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index cbc01a00eaf4..ef9d3399dfd2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -208,14 +208,14 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
208{ 208{
209 unsigned long flags; 209 unsigned long flags;
210 u16 radio_cfg; 210 u16 radio_cfg;
211 u8 val_link; 211 u16 link;
212 212
213 spin_lock_irqsave(&priv->lock, flags); 213 spin_lock_irqsave(&priv->lock, flags);
214 214
215 pci_read_config_byte(priv->pci_dev, PCI_LINK_CTRL, &val_link); 215 pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
216 216
217 /* L1 is enabled by BIOS */ 217 /* L1 is enabled by BIOS */
218 if ((val_link & PCI_LINK_VAL_L1_EN) == PCI_LINK_VAL_L1_EN) 218 if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
219 /* diable L0S disabled L1A enabled */ 219 /* diable L0S disabled L1A enabled */
220 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); 220 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
221 else 221 else
@@ -444,48 +444,6 @@ static int iwl5000_send_Xtal_calib(struct iwl_priv *priv)
444 sizeof(cal_cmd), &cal_cmd); 444 sizeof(cal_cmd), &cal_cmd);
445} 445}
446 446
447static int iwl5000_send_calib_results(struct iwl_priv *priv)
448{
449 int ret = 0;
450
451 struct iwl_host_cmd hcmd = {
452 .id = REPLY_PHY_CALIBRATION_CMD,
453 .meta.flags = CMD_SIZE_HUGE,
454 };
455
456 if (priv->calib_results.lo_res) {
457 hcmd.len = priv->calib_results.lo_res_len;
458 hcmd.data = priv->calib_results.lo_res;
459 ret = iwl_send_cmd_sync(priv, &hcmd);
460
461 if (ret)
462 goto err;
463 }
464
465 if (priv->calib_results.tx_iq_res) {
466 hcmd.len = priv->calib_results.tx_iq_res_len;
467 hcmd.data = priv->calib_results.tx_iq_res;
468 ret = iwl_send_cmd_sync(priv, &hcmd);
469
470 if (ret)
471 goto err;
472 }
473
474 if (priv->calib_results.tx_iq_perd_res) {
475 hcmd.len = priv->calib_results.tx_iq_perd_res_len;
476 hcmd.data = priv->calib_results.tx_iq_perd_res;
477 ret = iwl_send_cmd_sync(priv, &hcmd);
478
479 if (ret)
480 goto err;
481 }
482
483 return 0;
484err:
485 IWL_ERROR("Error %d\n", ret);
486 return ret;
487}
488
489static int iwl5000_send_calib_cfg(struct iwl_priv *priv) 447static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
490{ 448{
491 struct iwl5000_calib_cfg_cmd calib_cfg_cmd; 449 struct iwl5000_calib_cfg_cmd calib_cfg_cmd;
@@ -510,33 +468,30 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
510 struct iwl_rx_packet *pkt = (void *)rxb->skb->data; 468 struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
511 struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw; 469 struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw;
512 int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK; 470 int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK;
513 471 int index;
514 iwl_free_calib_results(priv);
515 472
516 /* reduce the size of the length field itself */ 473 /* reduce the size of the length field itself */
517 len -= 4; 474 len -= 4;
518 475
476 /* Define the order in which the results will be sent to the runtime
477 * uCode. iwl_send_calib_results sends them in a row according to their
478 * index. We sort them here */
519 switch (hdr->op_code) { 479 switch (hdr->op_code) {
520 case IWL5000_PHY_CALIBRATE_LO_CMD: 480 case IWL5000_PHY_CALIBRATE_LO_CMD:
521 priv->calib_results.lo_res = kzalloc(len, GFP_ATOMIC); 481 index = IWL5000_CALIB_LO;
522 priv->calib_results.lo_res_len = len;
523 memcpy(priv->calib_results.lo_res, pkt->u.raw, len);
524 break; 482 break;
525 case IWL5000_PHY_CALIBRATE_TX_IQ_CMD: 483 case IWL5000_PHY_CALIBRATE_TX_IQ_CMD:
526 priv->calib_results.tx_iq_res = kzalloc(len, GFP_ATOMIC); 484 index = IWL5000_CALIB_TX_IQ;
527 priv->calib_results.tx_iq_res_len = len;
528 memcpy(priv->calib_results.tx_iq_res, pkt->u.raw, len);
529 break; 485 break;
530 case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD: 486 case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD:
531 priv->calib_results.tx_iq_perd_res = kzalloc(len, GFP_ATOMIC); 487 index = IWL5000_CALIB_TX_IQ_PERD;
532 priv->calib_results.tx_iq_perd_res_len = len;
533 memcpy(priv->calib_results.tx_iq_perd_res, pkt->u.raw, len);
534 break; 488 break;
535 default: 489 default:
536 IWL_ERROR("Unknown calibration notification %d\n", 490 IWL_ERROR("Unknown calibration notification %d\n",
537 hdr->op_code); 491 hdr->op_code);
538 return; 492 return;
539 } 493 }
494 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
540} 495}
541 496
542static void iwl5000_rx_calib_complete(struct iwl_priv *priv, 497static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
@@ -834,7 +789,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
834 iwl5000_send_Xtal_calib(priv); 789 iwl5000_send_Xtal_calib(priv);
835 790
836 if (priv->ucode_type == UCODE_RT) 791 if (priv->ucode_type == UCODE_RT)
837 iwl5000_send_calib_results(priv); 792 iwl_send_calib_results(priv);
838 793
839 return 0; 794 return 0;
840} 795}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 754fef5b592f..35a6aeefaa25 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1668,6 +1668,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1668 return; 1668 return;
1669 1669
1670 lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv; 1670 lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
1671 lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
1671 1672
1672 tid = rs_tl_add_packet(lq_sta, hdr); 1673 tid = rs_tl_add_packet(lq_sta, hdr);
1673 1674
@@ -2216,8 +2217,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2216 sta->txrate_idx = i; 2217 sta->txrate_idx = i;
2217 2218
2218 sta->last_txrate_idx = sta->txrate_idx; 2219 sta->last_txrate_idx = sta->txrate_idx;
2219 /* WTF is with this bogus comment? A doesn't have cck rates */ 2220 /* For MODE_IEEE80211A, skip over cck rates in global rate table */
2220 /* For MODE_IEEE80211A, cck rates are at end of rate table */
2221 if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) 2221 if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
2222 sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 2222 sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2223 2223
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 676fc0acedee..5cce894dc1f9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1273,7 +1273,7 @@ int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
1273 1273
1274 if (src == IWL_PWR_SRC_VAUX) { 1274 if (src == IWL_PWR_SRC_VAUX) {
1275 u32 val; 1275 u32 val;
1276 ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE, 1276 ret = pci_read_config_dword(priv->pci_dev, PCI_CFG_POWER_SOURCE,
1277 &val); 1277 &val);
1278 1278
1279 if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) 1279 if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
@@ -2486,6 +2486,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
2486 if (!priv->vif || !priv->is_open) 2486 if (!priv->vif || !priv->is_open)
2487 return; 2487 return;
2488 2488
2489 iwl_power_cancel_timeout(priv);
2489 iwl_scan_cancel_timeout(priv, 200); 2490 iwl_scan_cancel_timeout(priv, 200);
2490 2491
2491 conf = ieee80211_get_hw_conf(priv->hw); 2492 conf = ieee80211_get_hw_conf(priv->hw);
@@ -2550,10 +2551,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
2550 break; 2551 break;
2551 } 2552 }
2552 2553
2553 /* Enable Rx differential gain and sensitivity calibrations */
2554 iwl_chain_noise_reset(priv);
2555 priv->start_calib = 1;
2556
2557 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) 2554 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
2558 priv->assoc_station_added = 1; 2555 priv->assoc_station_added = 1;
2559 2556
@@ -2561,7 +2558,12 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
2561 iwl_activate_qos(priv, 0); 2558 iwl_activate_qos(priv, 0);
2562 spin_unlock_irqrestore(&priv->lock, flags); 2559 spin_unlock_irqrestore(&priv->lock, flags);
2563 2560
2564 iwl_power_update_mode(priv, 0); 2561 iwl_power_enable_management(priv);
2562
2563 /* Enable Rx differential gain and sensitivity calibrations */
2564 iwl_chain_noise_reset(priv);
2565 priv->start_calib = 1;
2566
2565 /* we have just associated, don't start scan too early */ 2567 /* we have just associated, don't start scan too early */
2566 priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; 2568 priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
2567} 2569}
@@ -2720,12 +2722,6 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2720 2722
2721 IWL_DEBUG_MACDUMP("enter\n"); 2723 IWL_DEBUG_MACDUMP("enter\n");
2722 2724
2723 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
2724 IWL_DEBUG_MAC80211("leave - monitor\n");
2725 dev_kfree_skb_any(skb);
2726 return 0;
2727 }
2728
2729 IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, 2725 IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
2730 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); 2726 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
2731 2727
@@ -2841,7 +2837,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
2841 ) 2837 )
2842 priv->staging_rxon.flags = 0; 2838 priv->staging_rxon.flags = 0;
2843 2839
2844 iwl_set_rxon_channel(priv, conf->channel->band, channel); 2840 iwl_set_rxon_channel(priv, conf->channel);
2845 2841
2846 iwl_set_flags_for_band(priv, conf->channel->band); 2842 iwl_set_flags_for_band(priv, conf->channel->band);
2847 2843
@@ -3179,9 +3175,9 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
3179 3175
3180} 3176}
3181 3177
3182static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) 3178static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
3183{ 3179{
3184 int rc = 0; 3180 int ret;
3185 unsigned long flags; 3181 unsigned long flags;
3186 struct iwl_priv *priv = hw->priv; 3182 struct iwl_priv *priv = hw->priv;
3187 3183
@@ -3191,41 +3187,40 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
3191 spin_lock_irqsave(&priv->lock, flags); 3187 spin_lock_irqsave(&priv->lock, flags);
3192 3188
3193 if (!iwl_is_ready_rf(priv)) { 3189 if (!iwl_is_ready_rf(priv)) {
3194 rc = -EIO; 3190 ret = -EIO;
3195 IWL_DEBUG_MAC80211("leave - not ready or exit pending\n"); 3191 IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
3196 goto out_unlock; 3192 goto out_unlock;
3197 } 3193 }
3198 3194
3199 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { /* APs don't scan */ 3195 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { /* APs don't scan */
3200 rc = -EIO; 3196 ret = -EIO;
3201 IWL_ERROR("ERROR: APs don't scan\n"); 3197 IWL_ERROR("ERROR: APs don't scan\n");
3202 goto out_unlock; 3198 goto out_unlock;
3203 } 3199 }
3204 3200
3205 /* we don't schedule scan within next_scan_jiffies period */ 3201 /* we don't schedule scan within next_scan_jiffies period */
3206 if (priv->next_scan_jiffies && 3202 if (priv->next_scan_jiffies &&
3207 time_after(priv->next_scan_jiffies, jiffies)) { 3203 time_after(priv->next_scan_jiffies, jiffies)) {
3208 rc = -EAGAIN; 3204 IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
3205 ret = -EAGAIN;
3209 goto out_unlock; 3206 goto out_unlock;
3210 } 3207 }
3211 /* if we just finished scan ask for delay */ 3208 /* if we just finished scan ask for delay */
3212 if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies + 3209 if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
3213 IWL_DELAY_NEXT_SCAN, jiffies)) { 3210 time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
3214 rc = -EAGAIN; 3211 IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
3212 ret = -EAGAIN;
3215 goto out_unlock; 3213 goto out_unlock;
3216 } 3214 }
3217 if (len) { 3215 if (ssid_len) {
3218 IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
3219 iwl_escape_essid(ssid, len), (int)len);
3220
3221 priv->one_direct_scan = 1; 3216 priv->one_direct_scan = 1;
3222 priv->direct_ssid_len = (u8) 3217 priv->direct_ssid_len = min_t(u8, ssid_len, IW_ESSID_MAX_SIZE);
3223 min((u8) len, (u8) IW_ESSID_MAX_SIZE);
3224 memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len); 3218 memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
3225 } else 3219 } else {
3226 priv->one_direct_scan = 0; 3220 priv->one_direct_scan = 0;
3221 }
3227 3222
3228 rc = iwl_scan_initiate(priv); 3223 ret = iwl_scan_initiate(priv);
3229 3224
3230 IWL_DEBUG_MAC80211("leave\n"); 3225 IWL_DEBUG_MAC80211("leave\n");
3231 3226
@@ -3233,7 +3228,7 @@ out_unlock:
3233 spin_unlock_irqrestore(&priv->lock, flags); 3228 spin_unlock_irqrestore(&priv->lock, flags);
3234 mutex_unlock(&priv->mutex); 3229 mutex_unlock(&priv->mutex);
3235 3230
3236 return rc; 3231 return ret;
3237} 3232}
3238 3233
3239static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, 3234static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
@@ -3536,6 +3531,16 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
3536 /* Per mac80211.h: This is only used in IBSS mode... */ 3531 /* Per mac80211.h: This is only used in IBSS mode... */
3537 if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) { 3532 if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
3538 3533
3534 /* switch to CAM during association period.
3535 * the ucode will block any association/authentication
3536 * frome during assiciation period if it can not hear
3537 * the AP because of PM. the timer enable PM back is
3538 * association do not complete
3539 */
3540 if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
3541 IEEE80211_CHAN_RADAR))
3542 iwl_power_disable_management(priv, 3000);
3543
3539 IWL_DEBUG_MAC80211("leave - not in IBSS\n"); 3544 IWL_DEBUG_MAC80211("leave - not in IBSS\n");
3540 mutex_unlock(&priv->mutex); 3545 mutex_unlock(&priv->mutex);
3541 return; 3546 return;
@@ -3620,11 +3625,11 @@ static ssize_t store_debug_level(struct device *d,
3620 const char *buf, size_t count) 3625 const char *buf, size_t count)
3621{ 3626{
3622 struct iwl_priv *priv = d->driver_data; 3627 struct iwl_priv *priv = d->driver_data;
3623 char *p = (char *)buf; 3628 unsigned long val;
3624 u32 val; 3629 int ret;
3625 3630
3626 val = simple_strtoul(p, &p, 0); 3631 ret = strict_strtoul(buf, 0, &val);
3627 if (p == buf) 3632 if (ret)
3628 printk(KERN_INFO DRV_NAME 3633 printk(KERN_INFO DRV_NAME
3629 ": %s is not in hex or decimal form.\n", buf); 3634 ": %s is not in hex or decimal form.\n", buf);
3630 else 3635 else
@@ -3696,11 +3701,11 @@ static ssize_t store_tx_power(struct device *d,
3696 const char *buf, size_t count) 3701 const char *buf, size_t count)
3697{ 3702{
3698 struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; 3703 struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
3699 char *p = (char *)buf; 3704 unsigned long val;
3700 u32 val; 3705 int ret;
3701 3706
3702 val = simple_strtoul(p, &p, 10); 3707 ret = strict_strtoul(buf, 10, &val);
3703 if (p == buf) 3708 if (ret)
3704 printk(KERN_INFO DRV_NAME 3709 printk(KERN_INFO DRV_NAME
3705 ": %s is not in decimal form.\n", buf); 3710 ": %s is not in decimal form.\n", buf);
3706 else 3711 else
@@ -3724,7 +3729,12 @@ static ssize_t store_flags(struct device *d,
3724 const char *buf, size_t count) 3729 const char *buf, size_t count)
3725{ 3730{
3726 struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; 3731 struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
3727 u32 flags = simple_strtoul(buf, NULL, 0); 3732 unsigned long val;
3733 u32 flags;
3734 int ret = strict_strtoul(buf, 0, &val);
3735 if (ret)
3736 return ret;
3737 flags = (u32)val;
3728 3738
3729 mutex_lock(&priv->mutex); 3739 mutex_lock(&priv->mutex);
3730 if (le32_to_cpu(priv->staging_rxon.flags) != flags) { 3740 if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
@@ -3732,8 +3742,7 @@ static ssize_t store_flags(struct device *d,
3732 if (iwl_scan_cancel_timeout(priv, 100)) 3742 if (iwl_scan_cancel_timeout(priv, 100))
3733 IWL_WARNING("Could not cancel scan.\n"); 3743 IWL_WARNING("Could not cancel scan.\n");
3734 else { 3744 else {
3735 IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", 3745 IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags);
3736 flags);
3737 priv->staging_rxon.flags = cpu_to_le32(flags); 3746 priv->staging_rxon.flags = cpu_to_le32(flags);
3738 iwl4965_commit_rxon(priv); 3747 iwl4965_commit_rxon(priv);
3739 } 3748 }
@@ -3759,7 +3768,12 @@ static ssize_t store_filter_flags(struct device *d,
3759 const char *buf, size_t count) 3768 const char *buf, size_t count)
3760{ 3769{
3761 struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; 3770 struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
3762 u32 filter_flags = simple_strtoul(buf, NULL, 0); 3771 unsigned long val;
3772 u32 filter_flags;
3773 int ret = strict_strtoul(buf, 0, &val);
3774 if (ret)
3775 return ret;
3776 filter_flags = (u32)val;
3763 3777
3764 mutex_lock(&priv->mutex); 3778 mutex_lock(&priv->mutex);
3765 if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { 3779 if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
@@ -3860,10 +3874,12 @@ static ssize_t store_retry_rate(struct device *d,
3860 const char *buf, size_t count) 3874 const char *buf, size_t count)
3861{ 3875{
3862 struct iwl_priv *priv = dev_get_drvdata(d); 3876 struct iwl_priv *priv = dev_get_drvdata(d);
3877 long val;
3878 int ret = strict_strtol(buf, 10, &val);
3879 if (!ret)
3880 return ret;
3863 3881
3864 priv->retry_rate = simple_strtoul(buf, NULL, 0); 3882 priv->retry_rate = (val > 0) ? val : 1;
3865 if (priv->retry_rate <= 0)
3866 priv->retry_rate = 1;
3867 3883
3868 return count; 3884 return count;
3869} 3885}
@@ -3884,9 +3900,9 @@ static ssize_t store_power_level(struct device *d,
3884{ 3900{
3885 struct iwl_priv *priv = dev_get_drvdata(d); 3901 struct iwl_priv *priv = dev_get_drvdata(d);
3886 int ret; 3902 int ret;
3887 int mode; 3903 unsigned long mode;
3904
3888 3905
3889 mode = simple_strtoul(buf, NULL, 0);
3890 mutex_lock(&priv->mutex); 3906 mutex_lock(&priv->mutex);
3891 3907
3892 if (!iwl_is_ready(priv)) { 3908 if (!iwl_is_ready(priv)) {
@@ -3894,6 +3910,10 @@ static ssize_t store_power_level(struct device *d,
3894 goto out; 3910 goto out;
3895 } 3911 }
3896 3912
3913 ret = strict_strtoul(buf, 10, &mode);
3914 if (ret)
3915 goto out;
3916
3897 ret = iwl_power_set_user_mode(priv, mode); 3917 ret = iwl_power_set_user_mode(priv, mode);
3898 if (ret) { 3918 if (ret) {
3899 IWL_DEBUG_MAC80211("failed setting power mode.\n"); 3919 IWL_DEBUG_MAC80211("failed setting power mode.\n");
@@ -4073,6 +4093,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
4073 /* FIXME : remove when resolved PENDING */ 4093 /* FIXME : remove when resolved PENDING */
4074 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); 4094 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
4075 iwl_setup_scan_deferred_work(priv); 4095 iwl_setup_scan_deferred_work(priv);
4096 iwl_setup_power_deferred_work(priv);
4076 4097
4077 if (priv->cfg->ops->lib->setup_deferred_work) 4098 if (priv->cfg->ops->lib->setup_deferred_work)
4078 priv->cfg->ops->lib->setup_deferred_work(priv); 4099 priv->cfg->ops->lib->setup_deferred_work(priv);
@@ -4092,6 +4113,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
4092 4113
4093 cancel_delayed_work_sync(&priv->init_alive_start); 4114 cancel_delayed_work_sync(&priv->init_alive_start);
4094 cancel_delayed_work(&priv->scan_check); 4115 cancel_delayed_work(&priv->scan_check);
4116 cancel_delayed_work_sync(&priv->set_power_save);
4095 cancel_delayed_work(&priv->alive_start); 4117 cancel_delayed_work(&priv->alive_start);
4096 cancel_work_sync(&priv->beacon_update); 4118 cancel_work_sync(&priv->beacon_update);
4097 del_timer_sync(&priv->statistics_periodic); 4119 del_timer_sync(&priv->statistics_periodic);
@@ -4140,7 +4162,7 @@ static struct ieee80211_ops iwl4965_hw_ops = {
4140 .reset_tsf = iwl4965_mac_reset_tsf, 4162 .reset_tsf = iwl4965_mac_reset_tsf,
4141 .bss_info_changed = iwl4965_bss_info_changed, 4163 .bss_info_changed = iwl4965_bss_info_changed,
4142 .ampdu_action = iwl4965_mac_ampdu_action, 4164 .ampdu_action = iwl4965_mac_ampdu_action,
4143 .hw_scan = iwl4965_mac_hw_scan 4165 .hw_scan = iwl_mac_hw_scan
4144}; 4166};
4145 4167
4146static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 4168static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -4215,9 +4237,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4215 4237
4216 pci_set_drvdata(pdev, priv); 4238 pci_set_drvdata(pdev, priv);
4217 4239
4218 /* We disable the RETRY_TIMEOUT register (0x41) to keep
4219 * PCI Tx retries from interfering with C3 CPU state */
4220 pci_write_config_byte(pdev, 0x41, 0x00);
4221 4240
4222 /*********************** 4241 /***********************
4223 * 3. Read REV register 4242 * 3. Read REV register
@@ -4237,6 +4256,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4237 ": Detected Intel Wireless WiFi Link %s REV=0x%X\n", 4256 ": Detected Intel Wireless WiFi Link %s REV=0x%X\n",
4238 priv->cfg->name, priv->hw_rev); 4257 priv->cfg->name, priv->hw_rev);
4239 4258
4259 /* We disable the RETRY_TIMEOUT register (0x41) to keep
4260 * PCI Tx retries from interfering with C3 CPU state */
4261 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
4262
4240 /* amp init */ 4263 /* amp init */
4241 err = priv->cfg->ops->lib->apm_ops.init(priv); 4264 err = priv->cfg->ops->lib->apm_ops.init(priv);
4242 if (err < 0) { 4265 if (err < 0) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index ef49440bd7f6..35fb4a4f737d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -66,6 +66,66 @@
66#include "iwl-core.h" 66#include "iwl-core.h"
67#include "iwl-calib.h" 67#include "iwl-calib.h"
68 68
69/*****************************************************************************
70 * INIT calibrations framework
71 *****************************************************************************/
72
73 int iwl_send_calib_results(struct iwl_priv *priv)
74{
75 int ret = 0;
76 int i = 0;
77
78 struct iwl_host_cmd hcmd = {
79 .id = REPLY_PHY_CALIBRATION_CMD,
80 .meta.flags = CMD_SIZE_HUGE,
81 };
82
83 for (i = 0; i < IWL_CALIB_MAX; i++)
84 if (priv->calib_results[i].buf) {
85 hcmd.len = priv->calib_results[i].buf_len;
86 hcmd.data = priv->calib_results[i].buf;
87 ret = iwl_send_cmd_sync(priv, &hcmd);
88 if (ret)
89 goto err;
90 }
91
92 return 0;
93err:
94 IWL_ERROR("Error %d iteration %d\n", ret, i);
95 return ret;
96}
97EXPORT_SYMBOL(iwl_send_calib_results);
98
99int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len)
100{
101 if (res->buf_len != len) {
102 kfree(res->buf);
103 res->buf = kzalloc(len, GFP_ATOMIC);
104 }
105 if (unlikely(res->buf == NULL))
106 return -ENOMEM;
107
108 res->buf_len = len;
109 memcpy(res->buf, buf, len);
110 return 0;
111}
112EXPORT_SYMBOL(iwl_calib_set);
113
114void iwl_calib_free_results(struct iwl_priv *priv)
115{
116 int i;
117
118 for (i = 0; i < IWL_CALIB_MAX; i++) {
119 kfree(priv->calib_results[i].buf);
120 priv->calib_results[i].buf = NULL;
121 priv->calib_results[i].buf_len = 0;
122 }
123}
124
125/*****************************************************************************
126 * RUNTIME calibrations framework
127 *****************************************************************************/
128
69/* "false alarms" are signals that our DSP tries to lock onto, 129/* "false alarms" are signals that our DSP tries to lock onto,
70 * but then determines that they are either noise, or transmissions 130 * but then determines that they are either noise, or transmissions
71 * from a distant wireless network (also "noise", really) that get 131 * from a distant wireless network (also "noise", really) that get
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 28b5b09996ed..8d04e966ad48 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -163,6 +163,13 @@ enum {
163/* iwl_cmd_header flags value */ 163/* iwl_cmd_header flags value */
164#define IWL_CMD_FAILED_MSK 0x40 164#define IWL_CMD_FAILED_MSK 0x40
165 165
166#define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f)
167#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8)
168#define SEQ_TO_INDEX(s) ((s) & 0xff)
169#define INDEX_TO_SEQ(i) ((i) & 0xff)
170#define SEQ_HUGE_FRAME __constant_cpu_to_le16(0x4000)
171#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000)
172
166/** 173/**
167 * struct iwl_cmd_header 174 * struct iwl_cmd_header
168 * 175 *
@@ -171,7 +178,7 @@ enum {
171 */ 178 */
172struct iwl_cmd_header { 179struct iwl_cmd_header {
173 u8 cmd; /* Command ID: REPLY_RXON, etc. */ 180 u8 cmd; /* Command ID: REPLY_RXON, etc. */
174 u8 flags; /* IWL_CMD_* */ 181 u8 flags; /* 0:5 reserved, 6 abort, 7 internal */
175 /* 182 /*
176 * The driver sets up the sequence number to values of its chosing. 183 * The driver sets up the sequence number to values of its chosing.
177 * uCode does not use this value, but passes it back to the driver 184 * uCode does not use this value, but passes it back to the driver
@@ -187,11 +194,12 @@ struct iwl_cmd_header {
187 * 194 *
188 * The Linux driver uses the following format: 195 * The Linux driver uses the following format:
189 * 196 *
190 * 0:7 index/position within Tx queue 197 * 0:7 tfd index - position within TX queue
191 * 8:13 Tx queue selection 198 * 8:12 TX queue id
192 * 14:14 driver sets this to indicate command is in the 'huge' 199 * 13 reserved
193 * storage at the end of the command buffers, i.e. scan cmd 200 * 14 huge - driver sets this to indicate command is in the
194 * 15:15 uCode sets this in uCode-originated response/notification 201 * 'huge' storage at the end of the command buffers
202 * 15 unsolicited RX or uCode-originated notification
195 */ 203 */
196 __le16 sequence; 204 __le16 sequence;
197 205
@@ -2026,8 +2034,8 @@ struct iwl4965_spectrum_notification {
2026 * bit 2 - '0' PM have to walk up every DTIM 2034 * bit 2 - '0' PM have to walk up every DTIM
2027 * '1' PM could sleep over DTIM till listen Interval. 2035 * '1' PM could sleep over DTIM till listen Interval.
2028 * PCI power managed 2036 * PCI power managed
2029 * bit 3 - '0' (PCI_LINK_CTRL & 0x1) 2037 * bit 3 - '0' (PCI_CFG_LINK_CTRL & 0x1)
2030 * '1' !(PCI_LINK_CTRL & 0x1) 2038 * '1' !(PCI_CFG_LINK_CTRL & 0x1)
2031 * Force sleep Modes 2039 * Force sleep Modes
2032 * bit 31/30- '00' use both mac/xtal sleeps 2040 * bit 31/30- '00' use both mac/xtal sleeps
2033 * '01' force Mac sleep 2041 * '01' force Mac sleep
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index fbf75a62958d..1c5406487b11 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -773,7 +773,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
773EXPORT_SYMBOL(iwl_set_rxon_chain); 773EXPORT_SYMBOL(iwl_set_rxon_chain);
774 774
775/** 775/**
776 * iwlcore_set_rxon_channel - Set the phymode and channel values in staging RXON 776 * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON
777 * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz 777 * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
778 * @channel: Any channel valid for the requested phymode 778 * @channel: Any channel valid for the requested phymode
779 779
@@ -782,10 +782,11 @@ EXPORT_SYMBOL(iwl_set_rxon_chain);
782 * NOTE: Does not commit to the hardware; it sets appropriate bit fields 782 * NOTE: Does not commit to the hardware; it sets appropriate bit fields
783 * in the staging RXON flag structure based on the phymode 783 * in the staging RXON flag structure based on the phymode
784 */ 784 */
785int iwl_set_rxon_channel(struct iwl_priv *priv, 785int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
786 enum ieee80211_band band,
787 u16 channel)
788{ 786{
787 enum ieee80211_band band = ch->band;
788 u16 channel = ieee80211_frequency_to_channel(ch->center_freq);
789
789 if (!iwl_get_channel_info(priv, band, channel)) { 790 if (!iwl_get_channel_info(priv, band, channel)) {
790 IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", 791 IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
791 channel, band); 792 channel, band);
@@ -819,6 +820,10 @@ int iwl_setup_mac(struct iwl_priv *priv)
819 /* Tell mac80211 our characteristics */ 820 /* Tell mac80211 our characteristics */
820 hw->flags = IEEE80211_HW_SIGNAL_DBM | 821 hw->flags = IEEE80211_HW_SIGNAL_DBM |
821 IEEE80211_HW_NOISE_DBM; 822 IEEE80211_HW_NOISE_DBM;
823 hw->wiphy->interface_modes =
824 BIT(NL80211_IFTYPE_AP) |
825 BIT(NL80211_IFTYPE_STATION) |
826 BIT(NL80211_IFTYPE_ADHOC);
822 /* Default value; 4 EDCA QOS priorities */ 827 /* Default value; 4 EDCA QOS priorities */
823 hw->queues = 4; 828 hw->queues = 4;
824 /* queues to support 11n aggregation */ 829 /* queues to support 11n aggregation */
@@ -906,8 +911,6 @@ int iwl_init_drv(struct iwl_priv *priv)
906 priv->qos_data.qos_active = 0; 911 priv->qos_data.qos_active = 0;
907 priv->qos_data.qos_cap.val = 0; 912 priv->qos_data.qos_cap.val = 0;
908 913
909 iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
910
911 priv->rates_mask = IWL_RATES_MASK; 914 priv->rates_mask = IWL_RATES_MASK;
912 /* If power management is turned on, default to AC mode */ 915 /* If power management is turned on, default to AC mode */
913 priv->power_mode = IWL_POWER_AC; 916 priv->power_mode = IWL_POWER_AC;
@@ -934,22 +937,6 @@ err:
934} 937}
935EXPORT_SYMBOL(iwl_init_drv); 938EXPORT_SYMBOL(iwl_init_drv);
936 939
937void iwl_free_calib_results(struct iwl_priv *priv)
938{
939 kfree(priv->calib_results.lo_res);
940 priv->calib_results.lo_res = NULL;
941 priv->calib_results.lo_res_len = 0;
942
943 kfree(priv->calib_results.tx_iq_res);
944 priv->calib_results.tx_iq_res = NULL;
945 priv->calib_results.tx_iq_res_len = 0;
946
947 kfree(priv->calib_results.tx_iq_perd_res);
948 priv->calib_results.tx_iq_perd_res = NULL;
949 priv->calib_results.tx_iq_perd_res_len = 0;
950}
951EXPORT_SYMBOL(iwl_free_calib_results);
952
953int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) 940int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
954{ 941{
955 int ret = 0; 942 int ret = 0;
@@ -977,10 +964,9 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
977} 964}
978EXPORT_SYMBOL(iwl_set_tx_power); 965EXPORT_SYMBOL(iwl_set_tx_power);
979 966
980
981void iwl_uninit_drv(struct iwl_priv *priv) 967void iwl_uninit_drv(struct iwl_priv *priv)
982{ 968{
983 iwl_free_calib_results(priv); 969 iwl_calib_free_results(priv);
984 iwlcore_free_geos(priv); 970 iwlcore_free_geos(priv);
985 iwl_free_channel_map(priv); 971 iwl_free_channel_map(priv);
986 kfree(priv->scan); 972 kfree(priv->scan);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 64f139e97444..b5db050b22d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -186,12 +186,9 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
186void iwl_hw_detect(struct iwl_priv *priv); 186void iwl_hw_detect(struct iwl_priv *priv);
187 187
188void iwl_clear_stations_table(struct iwl_priv *priv); 188void iwl_clear_stations_table(struct iwl_priv *priv);
189void iwl_free_calib_results(struct iwl_priv *priv);
190void iwl_reset_qos(struct iwl_priv *priv); 189void iwl_reset_qos(struct iwl_priv *priv);
191void iwl_set_rxon_chain(struct iwl_priv *priv); 190void iwl_set_rxon_chain(struct iwl_priv *priv);
192int iwl_set_rxon_channel(struct iwl_priv *priv, 191int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
193 enum ieee80211_band band,
194 u16 channel);
195void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); 192void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
196u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, 193u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
197 struct ieee80211_ht_info *sta_ht_inf); 194 struct ieee80211_ht_info *sta_ht_inf);
@@ -291,6 +288,13 @@ int iwl_scan_initiate(struct iwl_priv *priv);
291void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); 288void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
292void iwl_setup_scan_deferred_work(struct iwl_priv *priv); 289void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
293 290
291/*******************************************************************************
292 * Calibrations - implemented in iwl-calib.c
293 ******************************************************************************/
294int iwl_send_calib_results(struct iwl_priv *priv);
295int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
296void iwl_calib_free_results(struct iwl_priv *priv);
297
294/***************************************************** 298/*****************************************************
295 * S e n d i n g H o s t C o m m a n d s * 299 * S e n d i n g H o s t C o m m a n d s *
296 *****************************************************/ 300 *****************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index f46e9cd1ca19..1943de3f7649 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -225,12 +225,6 @@ struct iwl_frame {
225 struct list_head list; 225 struct list_head list;
226}; 226};
227 227
228#define SEQ_TO_QUEUE(x) ((x >> 8) & 0xbf)
229#define QUEUE_TO_SEQ(x) ((x & 0xbf) << 8)
230#define SEQ_TO_INDEX(x) ((u8)(x & 0xff))
231#define INDEX_TO_SEQ(x) ((u8)(x & 0xff))
232#define SEQ_HUGE_FRAME (0x4000)
233#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000)
234#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) 228#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
235#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) 229#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
236#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) 230#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
@@ -637,12 +631,6 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
637 631
638struct iwl_priv; 632struct iwl_priv;
639 633
640/*
641 * Forward declare iwl-4965.c functions for iwl-base.c
642 */
643extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
644int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
645 u8 tid, int txq_id);
646 634
647/* Structures, enum, and defines specific to the 4965 */ 635/* Structures, enum, and defines specific to the 4965 */
648 636
@@ -734,13 +722,10 @@ struct statistics_general_data {
734 u32 beacon_energy_c; 722 u32 beacon_energy_c;
735}; 723};
736 724
737struct iwl_calib_results { 725/* Opaque calibration results */
738 void *tx_iq_res; 726struct iwl_calib_result {
739 void *tx_iq_perd_res; 727 void *buf;
740 void *lo_res; 728 size_t buf_len;
741 u32 tx_iq_res_len;
742 u32 tx_iq_perd_res_len;
743 u32 lo_res_len;
744}; 729};
745 730
746enum ucode_type { 731enum ucode_type {
@@ -802,6 +787,7 @@ enum {
802 787
803 788
804#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */ 789#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
790#define IWL_CALIB_MAX 3
805 791
806struct iwl_priv { 792struct iwl_priv {
807 793
@@ -845,7 +831,7 @@ struct iwl_priv {
845 s32 last_temperature; 831 s32 last_temperature;
846 832
847 /* init calibration results */ 833 /* init calibration results */
848 struct iwl_calib_results calib_results; 834 struct iwl_calib_result calib_results[IWL_CALIB_MAX];
849 835
850 /* Scan related variables */ 836 /* Scan related variables */
851 unsigned long last_scan_jiffies; 837 unsigned long last_scan_jiffies;
@@ -1032,6 +1018,7 @@ struct iwl_priv {
1032 1018
1033 struct tasklet_struct irq_tasklet; 1019 struct tasklet_struct irq_tasklet;
1034 1020
1021 struct delayed_work set_power_save;
1035 struct delayed_work init_alive_start; 1022 struct delayed_work init_alive_start;
1036 struct delayed_work alive_start; 1023 struct delayed_work alive_start;
1037 struct delayed_work scan_check; 1024 struct delayed_work scan_check;
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 5bc3df432d2d..9740fcc1805e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -61,7 +61,7 @@
61 * 61 *
62 */ 62 */
63 63
64#define _iwl_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs)) 64#define _iwl_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs))
65#ifdef CONFIG_IWLWIFI_DEBUG 65#ifdef CONFIG_IWLWIFI_DEBUG
66static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv, 66static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
67 u32 ofs, u32 val) 67 u32 ofs, u32 val)
@@ -75,7 +75,7 @@ static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
75#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val) 75#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val)
76#endif 76#endif
77 77
78#define _iwl_read32(priv, ofs) readl((priv)->hw_base + (ofs)) 78#define _iwl_read32(priv, ofs) ioread32((priv)->hw_base + (ofs))
79#ifdef CONFIG_IWLWIFI_DEBUG 79#ifdef CONFIG_IWLWIFI_DEBUG
80static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs) 80static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
81{ 81{
@@ -155,28 +155,10 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
155static inline int _iwl_grab_nic_access(struct iwl_priv *priv) 155static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
156{ 156{
157 int ret; 157 int ret;
158 u32 gp_ctl;
159
160#ifdef CONFIG_IWLWIFI_DEBUG 158#ifdef CONFIG_IWLWIFI_DEBUG
161 if (atomic_read(&priv->restrict_refcnt)) 159 if (atomic_read(&priv->restrict_refcnt))
162 return 0; 160 return 0;
163#endif 161#endif
164 if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
165 test_bit(STATUS_RF_KILL_SW, &priv->status)) {
166 IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
167 "wakes up NIC\n");
168
169 /* 10 msec allows time for NIC to complete its data save */
170 gp_ctl = _iwl_read32(priv, CSR_GP_CNTRL);
171 if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
172 IWL_DEBUG_RF_KILL("Wait for complete power-down, "
173 "gpctl = 0x%08x\n", gp_ctl);
174 mdelay(10);
175 } else
176 IWL_DEBUG_RF_KILL("power-down complete, "
177 "gpctl = 0x%08x\n", gp_ctl);
178 }
179
180 /* this bit wakes up the NIC */ 162 /* this bit wakes up the NIC */
181 _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 163 _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
182 ret = _iwl_poll_bit(priv, CSR_GP_CNTRL, 164 ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index a099c9e30e55..16f834d0c486 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -152,9 +152,10 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
152/* initialize to default */ 152/* initialize to default */
153static int iwl_power_init_handle(struct iwl_priv *priv) 153static int iwl_power_init_handle(struct iwl_priv *priv)
154{ 154{
155 int ret = 0, i;
156 struct iwl_power_mgr *pow_data; 155 struct iwl_power_mgr *pow_data;
157 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; 156 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
157 struct iwl_powertable_cmd *cmd;
158 int i;
158 u16 pci_pm; 159 u16 pci_pm;
159 160
160 IWL_DEBUG_POWER("Initialize power \n"); 161 IWL_DEBUG_POWER("Initialize power \n");
@@ -167,25 +168,19 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
167 memcpy(&pow_data->pwr_range_1[0], &range_1[0], size); 168 memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
168 memcpy(&pow_data->pwr_range_2[0], &range_2[0], size); 169 memcpy(&pow_data->pwr_range_2[0], &range_2[0], size);
169 170
170 ret = pci_read_config_word(priv->pci_dev, 171 pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &pci_pm);
171 PCI_LINK_CTRL, &pci_pm);
172 if (ret != 0)
173 return 0;
174 else {
175 struct iwl_powertable_cmd *cmd;
176 172
177 IWL_DEBUG_POWER("adjust power command flags\n"); 173 IWL_DEBUG_POWER("adjust power command flags\n");
178 174
179 for (i = 0; i < IWL_POWER_MAX; i++) { 175 for (i = 0; i < IWL_POWER_MAX; i++) {
180 cmd = &pow_data->pwr_range_0[i].cmd; 176 cmd = &pow_data->pwr_range_0[i].cmd;
181 177
182 if (pci_pm & 0x1) 178 if (pci_pm & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
183 cmd->flags &= ~IWL_POWER_PCI_PM_MSK; 179 cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
184 else 180 else
185 cmd->flags |= IWL_POWER_PCI_PM_MSK; 181 cmd->flags |= IWL_POWER_PCI_PM_MSK;
186 }
187 } 182 }
188 return ret; 183 return 0;
189} 184}
190 185
191/* adjust power command according to dtim period and power level*/ 186/* adjust power command according to dtim period and power level*/
@@ -324,7 +319,7 @@ EXPORT_SYMBOL(iwl_power_update_mode);
324 * this will be usefull for rate scale to disable PM during heavy 319 * this will be usefull for rate scale to disable PM during heavy
325 * Tx/Rx activities 320 * Tx/Rx activities
326 */ 321 */
327int iwl_power_disable_management(struct iwl_priv *priv) 322int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
328{ 323{
329 u16 prev_mode; 324 u16 prev_mode;
330 int ret = 0; 325 int ret = 0;
@@ -337,6 +332,11 @@ int iwl_power_disable_management(struct iwl_priv *priv)
337 ret = iwl_power_update_mode(priv, 0); 332 ret = iwl_power_update_mode(priv, 0);
338 priv->power_data.power_disabled = 1; 333 priv->power_data.power_disabled = 1;
339 priv->power_data.user_power_setting = prev_mode; 334 priv->power_data.user_power_setting = prev_mode;
335 cancel_delayed_work(&priv->set_power_save);
336 if (ms)
337 queue_delayed_work(priv->workqueue, &priv->set_power_save,
338 msecs_to_jiffies(ms));
339
340 340
341 return ret; 341 return ret;
342} 342}
@@ -431,3 +431,35 @@ int iwl_power_temperature_change(struct iwl_priv *priv)
431 return ret; 431 return ret;
432} 432}
433EXPORT_SYMBOL(iwl_power_temperature_change); 433EXPORT_SYMBOL(iwl_power_temperature_change);
434
435static void iwl_bg_set_power_save(struct work_struct *work)
436{
437 struct iwl_priv *priv = container_of(work,
438 struct iwl_priv, set_power_save.work);
439 IWL_DEBUG(IWL_DL_STATE, "update power\n");
440
441 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
442 return;
443
444 mutex_lock(&priv->mutex);
445
446 /* on starting association we disable power managment
447 * until association, if association failed then this
448 * timer will expire and enable PM again.
449 */
450 if (!iwl_is_associated(priv))
451 iwl_power_enable_management(priv);
452
453 mutex_unlock(&priv->mutex);
454}
455void iwl_setup_power_deferred_work(struct iwl_priv *priv)
456{
457 INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);
458}
459EXPORT_SYMBOL(iwl_setup_power_deferred_work);
460
461void iwl_power_cancel_timeout(struct iwl_priv *priv)
462{
463 cancel_delayed_work(&priv->set_power_save);
464}
465EXPORT_SYMBOL(iwl_power_cancel_timeout);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index abcbbf96a84e..aa99f3647def 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -78,8 +78,10 @@ struct iwl_power_mgr {
78 u8 power_disabled; /* flag to disable using power saving level */ 78 u8 power_disabled; /* flag to disable using power saving level */
79}; 79};
80 80
81void iwl_setup_power_deferred_work(struct iwl_priv *priv);
82void iwl_power_cancel_timeout(struct iwl_priv *priv);
81int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh); 83int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh);
82int iwl_power_disable_management(struct iwl_priv *priv); 84int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
83int iwl_power_enable_management(struct iwl_priv *priv); 85int iwl_power_enable_management(struct iwl_priv *priv);
84int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); 86int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
85int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode); 87int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 6283a3a707f5..5b7b05c8773f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -968,6 +968,11 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
968 iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); 968 iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
969 return priv->hw_params.bcast_sta_id; 969 return priv->hw_params.bcast_sta_id;
970 970
971 /* If we are in monitor mode, use BCAST. This is required for
972 * packet injection. */
973 case IEEE80211_IF_TYPE_MNTR:
974 return priv->hw_params.bcast_sta_id;
975
971 default: 976 default:
972 IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode); 977 IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
973 return priv->hw_params.bcast_sta_id; 978 return priv->hw_params.bcast_sta_id;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 6cba5e9c54ec..452938c299af 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -789,11 +789,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
789 goto drop_unlock; 789 goto drop_unlock;
790 } 790 }
791 791
792 if (!priv->vif) {
793 IWL_DEBUG_DROP("Dropping - !priv->vif\n");
794 goto drop_unlock;
795 }
796
797 if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == 792 if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
798 IWL_INVALID_RATE) { 793 IWL_INVALID_RATE) {
799 IWL_ERROR("ERROR: No TX rate available.\n"); 794 IWL_ERROR("ERROR: No TX rate available.\n");
@@ -815,9 +810,11 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
815 810
816 /* drop all data frame if we are not associated */ 811 /* drop all data frame if we are not associated */
817 if (ieee80211_is_data(fc) && 812 if (ieee80211_is_data(fc) &&
818 (!iwl_is_associated(priv) || 813 (priv->iw_mode != IEEE80211_IF_TYPE_MNTR ||
819 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) || 814 !(info->flags & IEEE80211_TX_CTL_INJECTED)) && /* packet injection */
820 !priv->assoc_station_added)) { 815 (!iwl_is_associated(priv) ||
816 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||
817 !priv->assoc_station_added)) {
821 IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n"); 818 IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
822 goto drop_unlock; 819 goto drop_unlock;
823 } 820 }
@@ -1057,7 +1054,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1057 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | 1054 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
1058 INDEX_TO_SEQ(q->write_ptr)); 1055 INDEX_TO_SEQ(q->write_ptr));
1059 if (out_cmd->meta.flags & CMD_SIZE_HUGE) 1056 if (out_cmd->meta.flags & CMD_SIZE_HUGE)
1060 out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME); 1057 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
1061 len = (idx == TFD_CMD_SLOTS) ? 1058 len = (idx == TFD_CMD_SLOTS) ?
1062 IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd); 1059 IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
1063 phys_addr = pci_map_single(priv->pci_dev, out_cmd, len, 1060 phys_addr = pci_map_single(priv->pci_dev, out_cmd, len,
@@ -1192,8 +1189,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1192 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 1189 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
1193 int txq_id = SEQ_TO_QUEUE(sequence); 1190 int txq_id = SEQ_TO_QUEUE(sequence);
1194 int index = SEQ_TO_INDEX(sequence); 1191 int index = SEQ_TO_INDEX(sequence);
1195 int huge = sequence & SEQ_HUGE_FRAME;
1196 int cmd_index; 1192 int cmd_index;
1193 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
1197 struct iwl_cmd *cmd; 1194 struct iwl_cmd *cmd;
1198 1195
1199 /* If a Tx command is being handled and it isn't in the actual 1196 /* If a Tx command is being handled and it isn't in the actual
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index a622fc33590a..cbbe73a12887 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4782,8 +4782,11 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
4782/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after 4782/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
4783 * sending probe req. This should be set long enough to hear probe responses 4783 * sending probe req. This should be set long enough to hear probe responses
4784 * from more than one AP. */ 4784 * from more than one AP. */
4785#define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */ 4785#define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */
4786#define IWL_ACTIVE_DWELL_TIME_52 (10) 4786#define IWL_ACTIVE_DWELL_TIME_52 (20)
4787
4788#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
4789#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
4787 4790
4788/* For faster active scanning, scan will move to the next channel if fewer than 4791/* For faster active scanning, scan will move to the next channel if fewer than
4789 * PLCP_QUIET_THRESH packets are heard on this channel within 4792 * PLCP_QUIET_THRESH packets are heard on this channel within
@@ -4792,7 +4795,7 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
4792 * no other traffic). 4795 * no other traffic).
4793 * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ 4796 * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
4794#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ 4797#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
4795#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */ 4798#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
4796 4799
4797/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. 4800/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
4798 * Must be set longer than active dwell time. 4801 * Must be set longer than active dwell time.
@@ -4802,19 +4805,23 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
4802#define IWL_PASSIVE_DWELL_BASE (100) 4805#define IWL_PASSIVE_DWELL_BASE (100)
4803#define IWL_CHANNEL_TUNE_TIME 5 4806#define IWL_CHANNEL_TUNE_TIME 5
4804 4807
4808#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
4809
4805static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, 4810static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
4806 enum ieee80211_band band) 4811 enum ieee80211_band band,
4812 u8 n_probes)
4807{ 4813{
4808 if (band == IEEE80211_BAND_5GHZ) 4814 if (band == IEEE80211_BAND_5GHZ)
4809 return IWL_ACTIVE_DWELL_TIME_52; 4815 return IWL_ACTIVE_DWELL_TIME_52 +
4816 IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
4810 else 4817 else
4811 return IWL_ACTIVE_DWELL_TIME_24; 4818 return IWL_ACTIVE_DWELL_TIME_24 +
4819 IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
4812} 4820}
4813 4821
4814static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, 4822static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
4815 enum ieee80211_band band) 4823 enum ieee80211_band band)
4816{ 4824{
4817 u16 active = iwl3945_get_active_dwell_time(priv, band);
4818 u16 passive = (band == IEEE80211_BAND_2GHZ) ? 4825 u16 passive = (band == IEEE80211_BAND_2GHZ) ?
4819 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : 4826 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
4820 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; 4827 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
@@ -4829,15 +4836,12 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
4829 passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; 4836 passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
4830 } 4837 }
4831 4838
4832 if (passive <= active)
4833 passive = active + 1;
4834
4835 return passive; 4839 return passive;
4836} 4840}
4837 4841
4838static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, 4842static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
4839 enum ieee80211_band band, 4843 enum ieee80211_band band,
4840 u8 is_active, u8 direct_mask, 4844 u8 is_active, u8 n_probes,
4841 struct iwl3945_scan_channel *scan_ch) 4845 struct iwl3945_scan_channel *scan_ch)
4842{ 4846{
4843 const struct ieee80211_channel *channels = NULL; 4847 const struct ieee80211_channel *channels = NULL;
@@ -4853,9 +4857,12 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
4853 4857
4854 channels = sband->channels; 4858 channels = sband->channels;
4855 4859
4856 active_dwell = iwl3945_get_active_dwell_time(priv, band); 4860 active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes);
4857 passive_dwell = iwl3945_get_passive_dwell_time(priv, band); 4861 passive_dwell = iwl3945_get_passive_dwell_time(priv, band);
4858 4862
4863 if (passive_dwell <= active_dwell)
4864 passive_dwell = active_dwell + 1;
4865
4859 for (i = 0, added = 0; i < sband->n_channels; i++) { 4866 for (i = 0, added = 0; i < sband->n_channels; i++) {
4860 if (channels[i].flags & IEEE80211_CHAN_DISABLED) 4867 if (channels[i].flags & IEEE80211_CHAN_DISABLED)
4861 continue; 4868 continue;
@@ -4875,8 +4882,8 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
4875 else 4882 else
4876 scan_ch->type = 1; /* active */ 4883 scan_ch->type = 1; /* active */
4877 4884
4878 if (scan_ch->type & 1) 4885 if ((scan_ch->type & 1) && n_probes)
4879 scan_ch->type |= (direct_mask << 1); 4886 scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
4880 4887
4881 scan_ch->active_dwell = cpu_to_le16(active_dwell); 4888 scan_ch->active_dwell = cpu_to_le16(active_dwell);
4882 scan_ch->passive_dwell = cpu_to_le16(passive_dwell); 4889 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
@@ -6093,7 +6100,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
6093 int rc = 0; 6100 int rc = 0;
6094 struct iwl3945_scan_cmd *scan; 6101 struct iwl3945_scan_cmd *scan;
6095 struct ieee80211_conf *conf = NULL; 6102 struct ieee80211_conf *conf = NULL;
6096 u8 direct_mask; 6103 u8 n_probes = 2;
6097 enum ieee80211_band band; 6104 enum ieee80211_band band;
6098 6105
6099 conf = ieee80211_get_hw_conf(priv->hw); 6106 conf = ieee80211_get_hw_conf(priv->hw);
@@ -6201,7 +6208,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
6201 scan->direct_scan[0].len = priv->direct_ssid_len; 6208 scan->direct_scan[0].len = priv->direct_ssid_len;
6202 memcpy(scan->direct_scan[0].ssid, 6209 memcpy(scan->direct_scan[0].ssid,
6203 priv->direct_ssid, priv->direct_ssid_len); 6210 priv->direct_ssid, priv->direct_ssid_len);
6204 direct_mask = 1; 6211 n_probes++;
6205 } else if (!iwl3945_is_associated(priv) && priv->essid_len) { 6212 } else if (!iwl3945_is_associated(priv) && priv->essid_len) {
6206 IWL_DEBUG_SCAN 6213 IWL_DEBUG_SCAN
6207 ("Kicking off one direct scan for '%s' when not associated\n", 6214 ("Kicking off one direct scan for '%s' when not associated\n",
@@ -6209,11 +6216,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
6209 scan->direct_scan[0].id = WLAN_EID_SSID; 6216 scan->direct_scan[0].id = WLAN_EID_SSID;
6210 scan->direct_scan[0].len = priv->essid_len; 6217 scan->direct_scan[0].len = priv->essid_len;
6211 memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); 6218 memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
6212 direct_mask = 1; 6219 n_probes++;
6213 } else { 6220 } else
6214 IWL_DEBUG_SCAN("Kicking off one indirect scan.\n"); 6221 IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
6215 direct_mask = 0;
6216 }
6217 6222
6218 /* We don't build a direct scan probe request; the uCode will do 6223 /* We don't build a direct scan probe request; the uCode will do
6219 * that based on the direct_mask added to each channel entry */ 6224 * that based on the direct_mask added to each channel entry */
@@ -6246,18 +6251,10 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
6246 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) 6251 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
6247 scan->filter_flags = RXON_FILTER_PROMISC_MSK; 6252 scan->filter_flags = RXON_FILTER_PROMISC_MSK;
6248 6253
6249 if (direct_mask) 6254 scan->channel_count =
6250 scan->channel_count = 6255 iwl3945_get_channels_for_scan(priv, band, 1, /* active */
6251 iwl3945_get_channels_for_scan( 6256 n_probes,
6252 priv, band, 1, /* active */ 6257 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
6253 direct_mask,
6254 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
6255 else
6256 scan->channel_count =
6257 iwl3945_get_channels_for_scan(
6258 priv, band, 0, /* passive */
6259 direct_mask,
6260 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
6261 6258
6262 cmd.len += le16_to_cpu(scan->tx_cmd.len) + 6259 cmd.len += le16_to_cpu(scan->tx_cmd.len) +
6263 scan->channel_count * sizeof(struct iwl3945_scan_channel); 6260 scan->channel_count * sizeof(struct iwl3945_scan_channel);
@@ -6320,11 +6317,8 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
6320 6317
6321#define IWL_DELAY_NEXT_SCAN (HZ*2) 6318#define IWL_DELAY_NEXT_SCAN (HZ*2)
6322 6319
6323static void iwl3945_bg_post_associate(struct work_struct *data) 6320static void iwl3945_post_associate(struct iwl3945_priv *priv)
6324{ 6321{
6325 struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv,
6326 post_associate.work);
6327
6328 int rc = 0; 6322 int rc = 0;
6329 struct ieee80211_conf *conf = NULL; 6323 struct ieee80211_conf *conf = NULL;
6330 DECLARE_MAC_BUF(mac); 6324 DECLARE_MAC_BUF(mac);
@@ -6342,12 +6336,9 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
6342 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 6336 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
6343 return; 6337 return;
6344 6338
6345 mutex_lock(&priv->mutex); 6339 if (!priv->vif || !priv->is_open)
6346
6347 if (!priv->vif || !priv->is_open) {
6348 mutex_unlock(&priv->mutex);
6349 return; 6340 return;
6350 } 6341
6351 iwl3945_scan_cancel_timeout(priv, 200); 6342 iwl3945_scan_cancel_timeout(priv, 200);
6352 6343
6353 conf = ieee80211_get_hw_conf(priv->hw); 6344 conf = ieee80211_get_hw_conf(priv->hw);
@@ -6419,7 +6410,6 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
6419 6410
6420 /* we have just associated, don't start scan too early */ 6411 /* we have just associated, don't start scan too early */
6421 priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; 6412 priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
6422 mutex_unlock(&priv->mutex);
6423} 6413}
6424 6414
6425static void iwl3945_bg_abort_scan(struct work_struct *work) 6415static void iwl3945_bg_abort_scan(struct work_struct *work)
@@ -6567,7 +6557,6 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
6567 */ 6557 */
6568 mutex_lock(&priv->mutex); 6558 mutex_lock(&priv->mutex);
6569 iwl3945_scan_cancel_timeout(priv, 100); 6559 iwl3945_scan_cancel_timeout(priv, 100);
6570 cancel_delayed_work(&priv->post_associate);
6571 mutex_unlock(&priv->mutex); 6560 mutex_unlock(&priv->mutex);
6572 } 6561 }
6573 6562
@@ -6933,7 +6922,6 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
6933 6922
6934 if (iwl3945_is_ready_rf(priv)) { 6923 if (iwl3945_is_ready_rf(priv)) {
6935 iwl3945_scan_cancel_timeout(priv, 100); 6924 iwl3945_scan_cancel_timeout(priv, 100);
6936 cancel_delayed_work(&priv->post_associate);
6937 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 6925 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
6938 iwl3945_commit_rxon(priv); 6926 iwl3945_commit_rxon(priv);
6939 } 6927 }
@@ -6948,6 +6936,63 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
6948 IWL_DEBUG_MAC80211("leave\n"); 6936 IWL_DEBUG_MAC80211("leave\n");
6949} 6937}
6950 6938
6939#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
6940
6941static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
6942 struct ieee80211_vif *vif,
6943 struct ieee80211_bss_conf *bss_conf,
6944 u32 changes)
6945{
6946 struct iwl3945_priv *priv = hw->priv;
6947
6948 IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
6949
6950 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
6951 IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
6952 bss_conf->use_short_preamble);
6953 if (bss_conf->use_short_preamble)
6954 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
6955 else
6956 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
6957 }
6958
6959 if (changes & BSS_CHANGED_ERP_CTS_PROT) {
6960 IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
6961 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
6962 priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
6963 else
6964 priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
6965 }
6966
6967 if (changes & BSS_CHANGED_ASSOC) {
6968 IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc);
6969 /* This should never happen as this function should
6970 * never be called from interrupt context. */
6971 if (WARN_ON_ONCE(in_interrupt()))
6972 return;
6973 if (bss_conf->assoc) {
6974 priv->assoc_id = bss_conf->aid;
6975 priv->beacon_int = bss_conf->beacon_int;
6976 priv->timestamp0 = bss_conf->timestamp & 0xFFFFFFFF;
6977 priv->timestamp1 = (bss_conf->timestamp >> 32) &
6978 0xFFFFFFFF;
6979 priv->assoc_capability = bss_conf->assoc_capability;
6980 priv->next_scan_jiffies = jiffies +
6981 IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
6982 mutex_lock(&priv->mutex);
6983 iwl3945_post_associate(priv);
6984 mutex_unlock(&priv->mutex);
6985 } else {
6986 priv->assoc_id = 0;
6987 IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
6988 }
6989 } else if (changes && iwl3945_is_associated(priv) && priv->assoc_id) {
6990 IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
6991 iwl3945_send_rxon_assoc(priv);
6992 }
6993
6994}
6995
6951static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) 6996static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
6952{ 6997{
6953 int rc = 0; 6998 int rc = 0;
@@ -7180,8 +7225,6 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
7180 7225
7181 iwl3945_reset_qos(priv); 7226 iwl3945_reset_qos(priv);
7182 7227
7183 cancel_delayed_work(&priv->post_associate);
7184
7185 spin_lock_irqsave(&priv->lock, flags); 7228 spin_lock_irqsave(&priv->lock, flags);
7186 priv->assoc_id = 0; 7229 priv->assoc_id = 0;
7187 priv->assoc_capability = 0; 7230 priv->assoc_capability = 0;
@@ -7266,7 +7309,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
7266 7309
7267 iwl3945_reset_qos(priv); 7310 iwl3945_reset_qos(priv);
7268 7311
7269 queue_work(priv->workqueue, &priv->post_associate.work); 7312 iwl3945_post_associate(priv);
7270 7313
7271 mutex_unlock(&priv->mutex); 7314 mutex_unlock(&priv->mutex);
7272 7315
@@ -7765,7 +7808,6 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
7765 INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); 7808 INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
7766 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); 7809 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
7767 INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor); 7810 INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor);
7768 INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate);
7769 INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); 7811 INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
7770 INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); 7812 INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
7771 INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); 7813 INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
@@ -7783,7 +7825,6 @@ static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv)
7783 cancel_delayed_work_sync(&priv->init_alive_start); 7825 cancel_delayed_work_sync(&priv->init_alive_start);
7784 cancel_delayed_work(&priv->scan_check); 7826 cancel_delayed_work(&priv->scan_check);
7785 cancel_delayed_work(&priv->alive_start); 7827 cancel_delayed_work(&priv->alive_start);
7786 cancel_delayed_work(&priv->post_associate);
7787 cancel_work_sync(&priv->beacon_update); 7828 cancel_work_sync(&priv->beacon_update);
7788} 7829}
7789 7830
@@ -7828,6 +7869,7 @@ static struct ieee80211_ops iwl3945_hw_ops = {
7828 .conf_tx = iwl3945_mac_conf_tx, 7869 .conf_tx = iwl3945_mac_conf_tx,
7829 .get_tsf = iwl3945_mac_get_tsf, 7870 .get_tsf = iwl3945_mac_get_tsf,
7830 .reset_tsf = iwl3945_mac_reset_tsf, 7871 .reset_tsf = iwl3945_mac_reset_tsf,
7872 .bss_info_changed = iwl3945_bss_info_changed,
7831 .hw_scan = iwl3945_mac_hw_scan 7873 .hw_scan = iwl3945_mac_hw_scan
7832}; 7874};
7833 7875
@@ -7888,6 +7930,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
7888 hw->flags = IEEE80211_HW_SIGNAL_DBM | 7930 hw->flags = IEEE80211_HW_SIGNAL_DBM |
7889 IEEE80211_HW_NOISE_DBM; 7931 IEEE80211_HW_NOISE_DBM;
7890 7932
7933 hw->wiphy->interface_modes =
7934 BIT(NL80211_IFTYPE_AP) |
7935 BIT(NL80211_IFTYPE_STATION) |
7936 BIT(NL80211_IFTYPE_ADHOC);
7937
7891 /* 4 EDCA QOS priorities */ 7938 /* 4 EDCA QOS priorities */
7892 hw->queues = 4; 7939 hw->queues = 4;
7893 7940
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 732429d49122..6ba50f087f7b 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -447,6 +447,9 @@ static int __init init_mac80211_hwsim(void)
447 447
448 hw->channel_change_time = 1; 448 hw->channel_change_time = 1;
449 hw->queues = 4; 449 hw->queues = 4;
450 hw->wiphy->interface_modes =
451 BIT(NL80211_IFTYPE_STATION) |
452 BIT(NL80211_IFTYPE_AP);
450 hw->ampdu_queues = 1; 453 hw->ampdu_queues = 1;
451 454
452 memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); 455 memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index fca8762fa069..98d4f8e7d84d 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -19,13 +19,24 @@ enum control_frame_types {
19 P54_CONTROL_TYPE_CHANNEL_CHANGE, 19 P54_CONTROL_TYPE_CHANNEL_CHANGE,
20 P54_CONTROL_TYPE_FREQDONE, 20 P54_CONTROL_TYPE_FREQDONE,
21 P54_CONTROL_TYPE_DCFINIT, 21 P54_CONTROL_TYPE_DCFINIT,
22 P54_CONTROL_TYPE_FREEQUEUE = 7, 22 P54_CONTROL_TYPE_ENCRYPTION,
23 P54_CONTROL_TYPE_TIM,
24 P54_CONTROL_TYPE_POWERMGT,
25 P54_CONTROL_TYPE_FREEQUEUE,
23 P54_CONTROL_TYPE_TXDONE, 26 P54_CONTROL_TYPE_TXDONE,
24 P54_CONTROL_TYPE_PING, 27 P54_CONTROL_TYPE_PING,
25 P54_CONTROL_TYPE_STAT_READBACK, 28 P54_CONTROL_TYPE_STAT_READBACK,
26 P54_CONTROL_TYPE_BBP, 29 P54_CONTROL_TYPE_BBP,
27 P54_CONTROL_TYPE_EEPROM_READBACK, 30 P54_CONTROL_TYPE_EEPROM_READBACK,
28 P54_CONTROL_TYPE_LED 31 P54_CONTROL_TYPE_LED,
32 P54_CONTROL_TYPE_GPIO,
33 P54_CONTROL_TYPE_TIMER,
34 P54_CONTROL_TYPE_MODULATION,
35 P54_CONTROL_TYPE_SYNTH_CONFIG,
36 P54_CONTROL_TYPE_DETECTOR_VALUE,
37 P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
38 P54_CONTROL_TYPE_CCE_QUIET,
39 P54_CONTROL_TYPE_PSM_STA_UNLOCK,
29}; 40};
30 41
31struct p54_control_hdr { 42struct p54_control_hdr {
@@ -38,11 +49,15 @@ struct p54_control_hdr {
38 u8 data[0]; 49 u8 data[0];
39} __attribute__ ((packed)); 50} __attribute__ ((packed));
40 51
41#define EEPROM_READBACK_LEN (sizeof(struct p54_control_hdr) + 4 /* p54_eeprom_lm86 */) 52#define EEPROM_READBACK_LEN 0x3fc
42#define MAX_RX_SIZE (IEEE80211_MAX_RTS_THRESHOLD + sizeof(struct p54_control_hdr) + 20 /* length of struct p54_rx_hdr */ + 16 )
43 53
44#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000 54#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
45 55
56#define FW_FMAC 0x464d4143
57#define FW_LM86 0x4c4d3836
58#define FW_LM87 0x4c4d3837
59#define FW_LM20 0x4c4d3230
60
46struct p54_common { 61struct p54_common {
47 u32 rx_start; 62 u32 rx_start;
48 u32 rx_end; 63 u32 rx_end;
@@ -53,26 +68,33 @@ struct p54_common {
53 void (*stop)(struct ieee80211_hw *dev); 68 void (*stop)(struct ieee80211_hw *dev);
54 int mode; 69 int mode;
55 u16 seqno; 70 u16 seqno;
71 u16 rx_mtu;
72 u8 headroom;
73 u8 tailroom;
56 struct mutex conf_mutex; 74 struct mutex conf_mutex;
57 u8 mac_addr[ETH_ALEN]; 75 u8 mac_addr[ETH_ALEN];
58 u8 bssid[ETH_ALEN]; 76 u8 bssid[ETH_ALEN];
77 __le16 filter_type;
59 struct pda_iq_autocal_entry *iq_autocal; 78 struct pda_iq_autocal_entry *iq_autocal;
60 unsigned int iq_autocal_len; 79 unsigned int iq_autocal_len;
61 struct pda_channel_output_limit *output_limit; 80 struct pda_channel_output_limit *output_limit;
62 unsigned int output_limit_len; 81 unsigned int output_limit_len;
63 struct pda_pa_curve_data *curve_data; 82 struct pda_pa_curve_data *curve_data;
64 __le16 rxhw; 83 u16 rxhw;
65 u8 version; 84 u8 version;
85 u8 rx_antenna;
66 unsigned int tx_hdr_len; 86 unsigned int tx_hdr_len;
67 void *cached_vdcf; 87 void *cached_vdcf;
68 unsigned int fw_var; 88 unsigned int fw_var;
89 unsigned int fw_interface;
69 struct ieee80211_tx_queue_stats tx_stats[8]; 90 struct ieee80211_tx_queue_stats tx_stats[8];
91 void *eeprom;
92 struct completion eeprom_comp;
70}; 93};
71 94
72int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); 95int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
73void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw); 96int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw);
74int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len); 97int p54_read_eeprom(struct ieee80211_hw *dev);
75void p54_fill_eeprom_readback(struct p54_control_hdr *hdr);
76struct ieee80211_hw *p54_init_common(size_t priv_data_len); 98struct ieee80211_hw *p54_init_common(size_t priv_data_len);
77void p54_free_common(struct ieee80211_hw *dev); 99void p54_free_common(struct ieee80211_hw *dev);
78 100
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 17e06bbc996a..f96f7c7e6af5 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -66,8 +66,7 @@ static struct ieee80211_supported_band band_2GHz = {
66 .n_bitrates = ARRAY_SIZE(p54_rates), 66 .n_bitrates = ARRAY_SIZE(p54_rates),
67}; 67};
68 68
69 69int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
70void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
71{ 70{
72 struct p54_common *priv = dev->priv; 71 struct p54_common *priv = dev->priv;
73 struct bootrec_exp_if *exp_if; 72 struct bootrec_exp_if *exp_if;
@@ -79,7 +78,7 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
79 int i; 78 int i;
80 79
81 if (priv->rx_start) 80 if (priv->rx_start)
82 return; 81 return 0;
83 82
84 while (data < end_data && *data) 83 while (data < end_data && *data)
85 data++; 84 data++;
@@ -94,7 +93,8 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
94 u32 code = le32_to_cpu(bootrec->code); 93 u32 code = le32_to_cpu(bootrec->code);
95 switch (code) { 94 switch (code) {
96 case BR_CODE_COMPONENT_ID: 95 case BR_CODE_COMPONENT_ID:
97 switch (be32_to_cpu(*(__be32 *)bootrec->data)) { 96 priv->fw_interface = be32_to_cpup(bootrec->data);
97 switch (priv->fw_interface) {
98 case FW_FMAC: 98 case FW_FMAC:
99 printk(KERN_INFO "p54: FreeMAC firmware\n"); 99 printk(KERN_INFO "p54: FreeMAC firmware\n");
100 break; 100 break;
@@ -105,7 +105,7 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
105 printk(KERN_INFO "p54: LM86 firmware\n"); 105 printk(KERN_INFO "p54: LM86 firmware\n");
106 break; 106 break;
107 case FW_LM87: 107 case FW_LM87:
108 printk(KERN_INFO "p54: LM87 firmware - not supported yet!\n"); 108 printk(KERN_INFO "p54: LM87 firmware\n");
109 break; 109 break;
110 default: 110 default:
111 printk(KERN_INFO "p54: unknown firmware\n"); 111 printk(KERN_INFO "p54: unknown firmware\n");
@@ -117,11 +117,22 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
117 if (strnlen((unsigned char*)bootrec->data, 24) < 24) 117 if (strnlen((unsigned char*)bootrec->data, 24) < 24)
118 fw_version = (unsigned char*)bootrec->data; 118 fw_version = (unsigned char*)bootrec->data;
119 break; 119 break;
120 case BR_CODE_DESCR: 120 case BR_CODE_DESCR: {
121 priv->rx_start = le32_to_cpu(((__le32 *)bootrec->data)[1]); 121 struct bootrec_desc *desc =
122 (struct bootrec_desc *)bootrec->data;
123 priv->rx_start = le32_to_cpu(desc->rx_start);
122 /* FIXME add sanity checking */ 124 /* FIXME add sanity checking */
123 priv->rx_end = le32_to_cpu(((__le32 *)bootrec->data)[2]) - 0x3500; 125 priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500;
126 priv->headroom = desc->headroom;
127 priv->tailroom = desc->tailroom;
128 if (bootrec->len == 11)
129 priv->rx_mtu = (size_t) le16_to_cpu(
130 (__le16)bootrec->data[10]);
131 else
132 priv->rx_mtu = (size_t)
133 0x620 - priv->tx_hdr_len;
124 break; 134 break;
135 }
125 case BR_CODE_EXPOSED_IF: 136 case BR_CODE_EXPOSED_IF:
126 exp_if = (struct bootrec_exp_if *) bootrec->data; 137 exp_if = (struct bootrec_exp_if *) bootrec->data;
127 for (i = 0; i < (len * sizeof(*exp_if) / 4); i++) 138 for (i = 0; i < (len * sizeof(*exp_if) / 4); i++)
@@ -152,6 +163,8 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
152 priv->tx_stats[7].limit = 1; 163 priv->tx_stats[7].limit = 1;
153 dev->queues = 4; 164 dev->queues = 4;
154 } 165 }
166
167 return 0;
155} 168}
156EXPORT_SYMBOL_GPL(p54_parse_firmware); 169EXPORT_SYMBOL_GPL(p54_parse_firmware);
157 170
@@ -237,6 +250,9 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
237 return 0; 250 return 0;
238} 251}
239 252
253const char* p54_rf_chips[] = { "NULL", "Indigo?", "Duette",
254 "Frisbee", "Xbow", "Longbow" };
255
240int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) 256int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
241{ 257{
242 struct p54_common *priv = dev->priv; 258 struct p54_common *priv = dev->priv;
@@ -246,6 +262,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
246 void *tmp; 262 void *tmp;
247 int err; 263 int err;
248 u8 *end = (u8 *)eeprom + len; 264 u8 *end = (u8 *)eeprom + len;
265 DECLARE_MAC_BUF(mac);
249 266
250 wrap = (struct eeprom_pda_wrap *) eeprom; 267 wrap = (struct eeprom_pda_wrap *) eeprom;
251 entry = (void *)wrap->data + le16_to_cpu(wrap->len); 268 entry = (void *)wrap->data + le16_to_cpu(wrap->len);
@@ -327,7 +344,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
327 while ((u8 *)tmp < entry->data + data_len) { 344 while ((u8 *)tmp < entry->data + data_len) {
328 struct bootrec_exp_if *exp_if = tmp; 345 struct bootrec_exp_if *exp_if = tmp;
329 if (le16_to_cpu(exp_if->if_id) == 0xF) 346 if (le16_to_cpu(exp_if->if_id) == 0xF)
330 priv->rxhw = exp_if->variant & cpu_to_le16(0x07); 347 priv->rxhw = le16_to_cpu(exp_if->variant) & 0x07;
331 tmp += sizeof(struct bootrec_exp_if); 348 tmp += sizeof(struct bootrec_exp_if);
332 } 349 }
333 break; 350 break;
@@ -353,6 +370,37 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
353 goto err; 370 goto err;
354 } 371 }
355 372
373 switch (priv->rxhw) {
374 case 4: /* XBow */
375 case 1: /* Indigo? */
376 case 2: /* Duette */
377 /* TODO: 5GHz initialization goes here */
378
379 case 3: /* Frisbee */
380 case 5: /* Longbow */
381 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
382 break;
383 default:
384 printk(KERN_ERR "%s: unsupported RF-Chip\n",
385 wiphy_name(dev->wiphy));
386 err = -EINVAL;
387 goto err;
388 }
389
390 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
391 u8 perm_addr[ETH_ALEN];
392
393 printk(KERN_WARNING "%s: Invalid hwaddr! Using randomly generated MAC addr\n",
394 wiphy_name(dev->wiphy));
395 random_ether_addr(perm_addr);
396 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
397 }
398
399 printk(KERN_INFO "%s: hwaddr %s, MAC:isl38%02x RF:%s\n",
400 wiphy_name(dev->wiphy),
401 print_mac(mac, dev->wiphy->perm_addr),
402 priv->version, p54_rf_chips[priv->rxhw]);
403
356 return 0; 404 return 0;
357 405
358 err: 406 err:
@@ -376,25 +424,12 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
376} 424}
377EXPORT_SYMBOL_GPL(p54_parse_eeprom); 425EXPORT_SYMBOL_GPL(p54_parse_eeprom);
378 426
379void p54_fill_eeprom_readback(struct p54_control_hdr *hdr) 427static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
380{
381 struct p54_eeprom_lm86 *eeprom_hdr;
382
383 hdr->magic1 = cpu_to_le16(0x8000);
384 hdr->len = cpu_to_le16(sizeof(*eeprom_hdr) + 0x2000);
385 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_EEPROM_READBACK);
386 hdr->retry1 = hdr->retry2 = 0;
387 eeprom_hdr = (struct p54_eeprom_lm86 *) hdr->data;
388 eeprom_hdr->offset = 0x0;
389 eeprom_hdr->len = cpu_to_le16(0x2000);
390}
391EXPORT_SYMBOL_GPL(p54_fill_eeprom_readback);
392
393static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
394{ 428{
395 struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data; 429 struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data;
396 struct ieee80211_rx_status rx_status = {0}; 430 struct ieee80211_rx_status rx_status = {0};
397 u16 freq = le16_to_cpu(hdr->freq); 431 u16 freq = le16_to_cpu(hdr->freq);
432 size_t header_len = sizeof(*hdr);
398 433
399 rx_status.signal = hdr->rssi; 434 rx_status.signal = hdr->rssi;
400 /* XX correct? */ 435 /* XX correct? */
@@ -406,10 +441,15 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
406 rx_status.mactime = le64_to_cpu(hdr->timestamp); 441 rx_status.mactime = le64_to_cpu(hdr->timestamp);
407 rx_status.flag |= RX_FLAG_TSFT; 442 rx_status.flag |= RX_FLAG_TSFT;
408 443
409 skb_pull(skb, sizeof(*hdr)); 444 if (hdr->magic & cpu_to_le16(0x4000))
445 header_len += hdr->align[0];
446
447 skb_pull(skb, header_len);
410 skb_trim(skb, le16_to_cpu(hdr->len)); 448 skb_trim(skb, le16_to_cpu(hdr->len));
411 449
412 ieee80211_rx_irqsafe(dev, skb, &rx_status); 450 ieee80211_rx_irqsafe(dev, skb, &rx_status);
451
452 return -1;
413} 453}
414 454
415static void inline p54_wake_free_queues(struct ieee80211_hw *dev) 455static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
@@ -428,7 +468,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
428 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data; 468 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
429 struct p54_frame_sent_hdr *payload = (struct p54_frame_sent_hdr *) hdr->data; 469 struct p54_frame_sent_hdr *payload = (struct p54_frame_sent_hdr *) hdr->data;
430 struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next; 470 struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next;
431 u32 addr = le32_to_cpu(hdr->req_id) - 0x70; 471 u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom;
432 struct memrecord *range = NULL; 472 struct memrecord *range = NULL;
433 u32 freed = 0; 473 u32 freed = 0;
434 u32 last_addr = priv->rx_start; 474 u32 last_addr = priv->rx_start;
@@ -487,7 +527,22 @@ out:
487 p54_wake_free_queues(dev); 527 p54_wake_free_queues(dev);
488} 528}
489 529
490static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb) 530static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
531 struct sk_buff *skb)
532{
533 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
534 struct p54_eeprom_lm86 *eeprom = (struct p54_eeprom_lm86 *) hdr->data;
535 struct p54_common *priv = dev->priv;
536
537 if (!priv->eeprom)
538 return ;
539
540 memcpy(priv->eeprom, eeprom->data, eeprom->len);
541
542 complete(&priv->eeprom_comp);
543}
544
545static int p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
491{ 546{
492 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data; 547 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
493 548
@@ -497,36 +552,27 @@ static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
497 break; 552 break;
498 case P54_CONTROL_TYPE_BBP: 553 case P54_CONTROL_TYPE_BBP:
499 break; 554 break;
555 case P54_CONTROL_TYPE_EEPROM_READBACK:
556 p54_rx_eeprom_readback(dev, skb);
557 break;
500 default: 558 default:
501 printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n", 559 printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n",
502 wiphy_name(dev->wiphy), le16_to_cpu(hdr->type)); 560 wiphy_name(dev->wiphy), le16_to_cpu(hdr->type));
503 break; 561 break;
504 } 562 }
563
564 return 0;
505} 565}
506 566
507/* returns zero if skb can be reused */ 567/* returns zero if skb can be reused */
508int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb) 568int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb)
509{ 569{
510 u8 type = le16_to_cpu(*((__le16 *)skb->data)) >> 8; 570 u8 type = le16_to_cpu(*((__le16 *)skb->data)) >> 8;
511 switch (type) { 571
512 case 0x00: 572 if (type == 0x80)
513 case 0x01: 573 return p54_rx_control(dev, skb);
514 p54_rx_data(dev, skb); 574 else
515 return -1; 575 return p54_rx_data(dev, skb);
516 case 0x4d:
517 /* TODO: do something better... but then again, I've never seen this happen */
518 printk(KERN_ERR "%s: Received fault. Probably need to restart hardware now..\n",
519 wiphy_name(dev->wiphy));
520 break;
521 case 0x80:
522 p54_rx_control(dev, skb);
523 break;
524 default:
525 printk(KERN_ERR "%s: unknown frame RXed (0x%02x)\n",
526 wiphy_name(dev->wiphy), type);
527 break;
528 }
529 return 0;
530} 576}
531EXPORT_SYMBOL_GPL(p54_rx); 577EXPORT_SYMBOL_GPL(p54_rx);
532 578
@@ -550,7 +596,7 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
550 u32 target_addr = priv->rx_start; 596 u32 target_addr = priv->rx_start;
551 unsigned long flags; 597 unsigned long flags;
552 unsigned int left; 598 unsigned int left;
553 len = (len + 0x170 + 3) & ~0x3; /* 0x70 headroom, 0x100 tailroom */ 599 len = (len + priv->headroom + priv->tailroom + 3) & ~0x3;
554 600
555 spin_lock_irqsave(&priv->tx_queue.lock, flags); 601 spin_lock_irqsave(&priv->tx_queue.lock, flags);
556 left = skb_queue_len(&priv->tx_queue); 602 left = skb_queue_len(&priv->tx_queue);
@@ -585,15 +631,74 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
585 range->start_addr = target_addr; 631 range->start_addr = target_addr;
586 range->end_addr = target_addr + len; 632 range->end_addr = target_addr + len;
587 __skb_queue_after(&priv->tx_queue, target_skb, skb); 633 __skb_queue_after(&priv->tx_queue, target_skb, skb);
588 if (largest_hole < IEEE80211_MAX_RTS_THRESHOLD + 0x170 + 634 if (largest_hole < priv->rx_mtu + priv->headroom +
635 priv->tailroom +
589 sizeof(struct p54_control_hdr)) 636 sizeof(struct p54_control_hdr))
590 ieee80211_stop_queues(dev); 637 ieee80211_stop_queues(dev);
591 } 638 }
592 spin_unlock_irqrestore(&priv->tx_queue.lock, flags); 639 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
593 640
594 data->req_id = cpu_to_le32(target_addr + 0x70); 641 data->req_id = cpu_to_le32(target_addr + priv->headroom);
595} 642}
596 643
644int p54_read_eeprom(struct ieee80211_hw *dev)
645{
646 struct p54_common *priv = dev->priv;
647 struct p54_control_hdr *hdr = NULL;
648 struct p54_eeprom_lm86 *eeprom_hdr;
649 size_t eeprom_size = 0x2020, offset = 0, blocksize;
650 int ret = -ENOMEM;
651 void *eeprom = NULL;
652
653 hdr = (struct p54_control_hdr *)kzalloc(sizeof(*hdr) +
654 sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN, GFP_KERNEL);
655 if (!hdr)
656 goto free;
657
658 priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL);
659 if (!priv->eeprom)
660 goto free;
661
662 eeprom = kzalloc(eeprom_size, GFP_KERNEL);
663 if (!eeprom)
664 goto free;
665
666 hdr->magic1 = cpu_to_le16(0x8000);
667 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_EEPROM_READBACK);
668 hdr->retry1 = hdr->retry2 = 0;
669 eeprom_hdr = (struct p54_eeprom_lm86 *) hdr->data;
670
671 while (eeprom_size) {
672 blocksize = min(eeprom_size, (size_t)EEPROM_READBACK_LEN);
673 hdr->len = cpu_to_le16(blocksize + sizeof(*eeprom_hdr));
674 eeprom_hdr->offset = cpu_to_le16(offset);
675 eeprom_hdr->len = cpu_to_le16(blocksize);
676 p54_assign_address(dev, NULL, hdr, hdr->len + sizeof(*hdr));
677 priv->tx(dev, hdr, hdr->len + sizeof(*hdr), 0);
678
679 if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) {
680 printk(KERN_ERR "%s: device does not respond!\n",
681 wiphy_name(dev->wiphy));
682 ret = -EBUSY;
683 goto free;
684 }
685
686 memcpy(eeprom + offset, priv->eeprom, blocksize);
687 offset += blocksize;
688 eeprom_size -= blocksize;
689 }
690
691 ret = p54_parse_eeprom(dev, eeprom, offset);
692free:
693 kfree(priv->eeprom);
694 priv->eeprom = NULL;
695 kfree(hdr);
696 kfree(eeprom);
697
698 return ret;
699}
700EXPORT_SYMBOL_GPL(p54_read_eeprom);
701
597static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) 702static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
598{ 703{
599 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 704 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -675,12 +780,12 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
675} 780}
676 781
677static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type, 782static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
678 const u8 *dst, const u8 *src, u8 antenna, 783 const u8 *bssid)
679 u32 magic3, u32 magic8, u32 magic9)
680{ 784{
681 struct p54_common *priv = dev->priv; 785 struct p54_common *priv = dev->priv;
682 struct p54_control_hdr *hdr; 786 struct p54_control_hdr *hdr;
683 struct p54_tx_control_filter *filter; 787 struct p54_tx_control_filter *filter;
788 size_t data_len;
684 789
685 hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) + 790 hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
686 priv->tx_hdr_len, GFP_ATOMIC); 791 priv->tx_hdr_len, GFP_ATOMIC);
@@ -691,25 +796,35 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
691 796
692 filter = (struct p54_tx_control_filter *) hdr->data; 797 filter = (struct p54_tx_control_filter *) hdr->data;
693 hdr->magic1 = cpu_to_le16(0x8001); 798 hdr->magic1 = cpu_to_le16(0x8001);
694 hdr->len = cpu_to_le16(sizeof(*filter));
695 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter));
696 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET); 799 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET);
697 800
698 filter->filter_type = cpu_to_le16(filter_type); 801 priv->filter_type = filter->filter_type = cpu_to_le16(filter_type);
699 memcpy(filter->dst, dst, ETH_ALEN); 802 memcpy(filter->mac_addr, priv->mac_addr, ETH_ALEN);
700 if (!src) 803 if (!bssid)
701 memset(filter->src, ~0, ETH_ALEN); 804 memset(filter->bssid, ~0, ETH_ALEN);
702 else 805 else
703 memcpy(filter->src, src, ETH_ALEN); 806 memcpy(filter->bssid, bssid, ETH_ALEN);
704 filter->antenna = antenna; 807
705 filter->magic3 = cpu_to_le32(magic3); 808 filter->rx_antenna = priv->rx_antenna;
706 filter->rx_addr = cpu_to_le32(priv->rx_end); 809
707 filter->max_rx = cpu_to_le16(0x0620); /* FIXME: for usb ver 1.. maybe */ 810 if (priv->fw_var < 0x500) {
708 filter->rxhw = priv->rxhw; 811 data_len = P54_TX_CONTROL_FILTER_V1_LEN;
709 filter->magic8 = cpu_to_le16(magic8); 812 filter->v1.basic_rate_mask = cpu_to_le32(0x15F);
710 filter->magic9 = cpu_to_le16(magic9); 813 filter->v1.rx_addr = cpu_to_le32(priv->rx_end);
711 814 filter->v1.max_rx = cpu_to_le16(priv->rx_mtu);
712 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*filter), 1); 815 filter->v1.rxhw = cpu_to_le16(priv->rxhw);
816 filter->v1.wakeup_timer = cpu_to_le16(500);
817 } else {
818 data_len = P54_TX_CONTROL_FILTER_V2_LEN;
819 filter->v2.rx_addr = cpu_to_le32(priv->rx_end);
820 filter->v2.max_rx = cpu_to_le16(priv->rx_mtu);
821 filter->v2.rxhw = cpu_to_le16(priv->rxhw);
822 filter->v2.timer = cpu_to_le16(1000);
823 }
824
825 hdr->len = cpu_to_le16(data_len);
826 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + data_len);
827 priv->tx(dev, hdr, sizeof(*hdr) + data_len, 1);
713 return 0; 828 return 0;
714} 829}
715 830
@@ -719,6 +834,7 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
719 struct p54_control_hdr *hdr; 834 struct p54_control_hdr *hdr;
720 struct p54_tx_control_channel *chan; 835 struct p54_tx_control_channel *chan;
721 unsigned int i; 836 unsigned int i;
837 size_t data_len;
722 void *entry; 838 void *entry;
723 839
724 hdr = kzalloc(sizeof(*hdr) + sizeof(*chan) + 840 hdr = kzalloc(sizeof(*hdr) + sizeof(*chan) +
@@ -731,9 +847,8 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
731 chan = (struct p54_tx_control_channel *) hdr->data; 847 chan = (struct p54_tx_control_channel *) hdr->data;
732 848
733 hdr->magic1 = cpu_to_le16(0x8001); 849 hdr->magic1 = cpu_to_le16(0x8001);
734 hdr->len = cpu_to_le16(sizeof(*chan)); 850
735 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE); 851 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
736 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*chan));
737 852
738 chan->flags = cpu_to_le16(0x1); 853 chan->flags = cpu_to_le16(0x1);
739 chan->dwell = cpu_to_le16(0x0); 854 chan->dwell = cpu_to_le16(0x0);
@@ -785,10 +900,20 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
785 break; 900 break;
786 } 901 }
787 902
788 chan->rssical_mul = cpu_to_le16(130); 903 if (priv->fw_var < 0x500) {
789 chan->rssical_add = cpu_to_le16(0xfe70); /* -400 */ 904 data_len = P54_TX_CONTROL_CHANNEL_V1_LEN;
905 chan->v1.rssical_mul = cpu_to_le16(130);
906 chan->v1.rssical_add = cpu_to_le16(0xfe70);
907 } else {
908 data_len = P54_TX_CONTROL_CHANNEL_V2_LEN;
909 chan->v2.rssical_mul = cpu_to_le16(130);
910 chan->v2.rssical_add = cpu_to_le16(0xfe70);
911 chan->v2.basic_rate_mask = cpu_to_le32(0x15f);
912 }
790 913
791 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*chan), 1); 914 hdr->len = cpu_to_le16(data_len);
915 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + data_len);
916 priv->tx(dev, hdr, sizeof(*hdr) + data_len, 1);
792 return 0; 917 return 0;
793 918
794 err: 919 err:
@@ -933,12 +1058,11 @@ static int p54_add_interface(struct ieee80211_hw *dev,
933 1058
934 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); 1059 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
935 1060
936 p54_set_filter(dev, 0, priv->mac_addr, NULL, 0, 1, 0, 0xF642); 1061 p54_set_filter(dev, 0, NULL);
937 p54_set_filter(dev, 0, priv->mac_addr, NULL, 1, 0, 0, 0xF642);
938 1062
939 switch (conf->type) { 1063 switch (conf->type) {
940 case IEEE80211_IF_TYPE_STA: 1064 case IEEE80211_IF_TYPE_STA:
941 p54_set_filter(dev, 1, priv->mac_addr, NULL, 0, 0x15F, 0x1F4, 0); 1065 p54_set_filter(dev, 1, NULL);
942 break; 1066 break;
943 default: 1067 default:
944 BUG(); /* impossible */ 1068 BUG(); /* impossible */
@@ -956,7 +1080,7 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
956 struct p54_common *priv = dev->priv; 1080 struct p54_common *priv = dev->priv;
957 priv->mode = IEEE80211_IF_TYPE_MNTR; 1081 priv->mode = IEEE80211_IF_TYPE_MNTR;
958 memset(priv->mac_addr, 0, ETH_ALEN); 1082 memset(priv->mac_addr, 0, ETH_ALEN);
959 p54_set_filter(dev, 0, priv->mac_addr, NULL, 2, 0, 0, 0); 1083 p54_set_filter(dev, 0, NULL);
960} 1084}
961 1085
962static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 1086static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
@@ -965,6 +1089,8 @@ static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
965 struct p54_common *priv = dev->priv; 1089 struct p54_common *priv = dev->priv;
966 1090
967 mutex_lock(&priv->conf_mutex); 1091 mutex_lock(&priv->conf_mutex);
1092 priv->rx_antenna = (conf->antenna_sel_rx == 0) ?
1093 2 : conf->antenna_sel_tx - 1;
968 ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq)); 1094 ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
969 p54_set_vdcf(dev); 1095 p54_set_vdcf(dev);
970 mutex_unlock(&priv->conf_mutex); 1096 mutex_unlock(&priv->conf_mutex);
@@ -978,8 +1104,7 @@ static int p54_config_interface(struct ieee80211_hw *dev,
978 struct p54_common *priv = dev->priv; 1104 struct p54_common *priv = dev->priv;
979 1105
980 mutex_lock(&priv->conf_mutex); 1106 mutex_lock(&priv->conf_mutex);
981 p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 0, 1, 0, 0xF642); 1107 p54_set_filter(dev, 0, conf->bssid);
982 p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 2, 0, 0, 0);
983 p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0); 1108 p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
984 memcpy(priv->bssid, conf->bssid, ETH_ALEN); 1109 memcpy(priv->bssid, conf->bssid, ETH_ALEN);
985 mutex_unlock(&priv->conf_mutex); 1110 mutex_unlock(&priv->conf_mutex);
@@ -997,11 +1122,9 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
997 1122
998 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { 1123 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
999 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) 1124 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
1000 p54_set_filter(dev, 0, priv->mac_addr, 1125 p54_set_filter(dev, 0, NULL);
1001 NULL, 2, 0, 0, 0);
1002 else 1126 else
1003 p54_set_filter(dev, 0, priv->mac_addr, 1127 p54_set_filter(dev, 0, priv->bssid);
1004 priv->bssid, 2, 0, 0, 0);
1005 } 1128 }
1006} 1129}
1007 1130
@@ -1068,10 +1191,12 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
1068 priv = dev->priv; 1191 priv = dev->priv;
1069 priv->mode = IEEE80211_IF_TYPE_INVALID; 1192 priv->mode = IEEE80211_IF_TYPE_INVALID;
1070 skb_queue_head_init(&priv->tx_queue); 1193 skb_queue_head_init(&priv->tx_queue);
1071 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
1072 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ 1194 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
1073 IEEE80211_HW_RX_INCLUDES_FCS | 1195 IEEE80211_HW_RX_INCLUDES_FCS |
1074 IEEE80211_HW_SIGNAL_UNSPEC; 1196 IEEE80211_HW_SIGNAL_UNSPEC;
1197
1198 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1199
1075 dev->channel_change_time = 1000; /* TODO: find actual value */ 1200 dev->channel_change_time = 1000; /* TODO: find actual value */
1076 dev->max_signal = 127; 1201 dev->max_signal = 127;
1077 1202
@@ -1081,11 +1206,11 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
1081 priv->tx_stats[3].limit = 1; 1206 priv->tx_stats[3].limit = 1;
1082 priv->tx_stats[4].limit = 5; 1207 priv->tx_stats[4].limit = 5;
1083 dev->queues = 1; 1208 dev->queues = 1;
1084
1085 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 + 1209 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
1086 sizeof(struct p54_tx_control_allocdata); 1210 sizeof(struct p54_tx_control_allocdata);
1087 1211
1088 mutex_init(&priv->conf_mutex); 1212 mutex_init(&priv->conf_mutex);
1213 init_completion(&priv->eeprom_comp);
1089 1214
1090 return dev; 1215 return dev;
1091} 1216}
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index a79c1a146917..73a9a2c923dd 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -29,6 +29,17 @@ struct bootrec_exp_if {
29 __le16 top_compat; 29 __le16 top_compat;
30} __attribute__((packed)); 30} __attribute__((packed));
31 31
32struct bootrec_desc {
33 __le16 modes;
34 __le16 flags;
35 __le32 rx_start;
36 __le32 rx_end;
37 u8 headroom;
38 u8 tailroom;
39 u8 unimportant[6];
40 u8 rates[16];
41} __attribute__((packed));
42
32#define BR_CODE_MIN 0x80000000 43#define BR_CODE_MIN 0x80000000
33#define BR_CODE_COMPONENT_ID 0x80000001 44#define BR_CODE_COMPONENT_ID 0x80000001
34#define BR_CODE_COMPONENT_VERSION 0x80000002 45#define BR_CODE_COMPONENT_VERSION 0x80000002
@@ -39,11 +50,6 @@ struct bootrec_exp_if {
39#define BR_CODE_END_OF_BRA 0xFF0000FF 50#define BR_CODE_END_OF_BRA 0xFF0000FF
40#define LEGACY_BR_CODE_END_OF_BRA 0xFFFFFFFF 51#define LEGACY_BR_CODE_END_OF_BRA 0xFFFFFFFF
41 52
42#define FW_FMAC 0x464d4143
43#define FW_LM86 0x4c4d3836
44#define FW_LM87 0x4c4d3837
45#define FW_LM20 0x4c4d3230
46
47/* PDA defines are Copyright (C) 2005 Nokia Corporation (taken from islsm_pda.h) */ 53/* PDA defines are Copyright (C) 2005 Nokia Corporation (taken from islsm_pda.h) */
48 54
49struct pda_entry { 55struct pda_entry {
@@ -180,7 +186,7 @@ struct p54_rx_hdr {
180 u8 quality; 186 u8 quality;
181 u16 unknown2; 187 u16 unknown2;
182 __le64 timestamp; 188 __le64 timestamp;
183 u8 data[0]; 189 u8 align[0];
184} __attribute__ ((packed)); 190} __attribute__ ((packed));
185 191
186struct p54_frame_sent_hdr { 192struct p54_frame_sent_hdr {
@@ -208,19 +214,34 @@ struct p54_tx_control_allocdata {
208 214
209struct p54_tx_control_filter { 215struct p54_tx_control_filter {
210 __le16 filter_type; 216 __le16 filter_type;
211 u8 dst[ETH_ALEN]; 217 u8 mac_addr[ETH_ALEN];
212 u8 src[ETH_ALEN]; 218 u8 bssid[ETH_ALEN];
213 u8 antenna; 219 u8 rx_antenna;
214 u8 debug; 220 u8 rx_align;
215 __le32 magic3; 221 union {
216 u8 rates[8]; // FIXME: what's this for? 222 struct {
217 __le32 rx_addr; 223 __le32 basic_rate_mask;
218 __le16 max_rx; 224 u8 rts_rates[8];
219 __le16 rxhw; 225 __le32 rx_addr;
220 __le16 magic8; 226 __le16 max_rx;
221 __le16 magic9; 227 __le16 rxhw;
228 __le16 wakeup_timer;
229 __le16 unalloc0;
230 } v1 __attribute__ ((packed));
231 struct {
232 __le32 rx_addr;
233 __le16 max_rx;
234 __le16 rxhw;
235 __le16 timer;
236 __le16 unalloc0;
237 __le32 unalloc1;
238 } v2 __attribute__ ((packed));
239 } __attribute__ ((packed));
222} __attribute__ ((packed)); 240} __attribute__ ((packed));
223 241
242#define P54_TX_CONTROL_FILTER_V1_LEN (sizeof(struct p54_tx_control_filter))
243#define P54_TX_CONTROL_FILTER_V2_LEN (sizeof(struct p54_tx_control_filter)-8)
244
224struct p54_tx_control_channel { 245struct p54_tx_control_channel {
225 __le16 flags; 246 __le16 flags;
226 __le16 dwell; 247 __le16 dwell;
@@ -232,15 +253,29 @@ struct p54_tx_control_channel {
232 u8 val_qpsk; 253 u8 val_qpsk;
233 u8 val_16qam; 254 u8 val_16qam;
234 u8 val_64qam; 255 u8 val_64qam;
235 struct pda_pa_curve_data_sample_rev1 curve_data[8]; 256 struct p54_pa_curve_data_sample curve_data[8];
236 u8 dup_bpsk; 257 u8 dup_bpsk;
237 u8 dup_qpsk; 258 u8 dup_qpsk;
238 u8 dup_16qam; 259 u8 dup_16qam;
239 u8 dup_64qam; 260 u8 dup_64qam;
240 __le16 rssical_mul; 261 union {
241 __le16 rssical_add; 262 struct {
263 __le16 rssical_mul;
264 __le16 rssical_add;
265 } v1 __attribute__ ((packed));
266
267 struct {
268 __le32 basic_rate_mask;
269 u8 rts_rates[8];
270 __le16 rssical_mul;
271 __le16 rssical_add;
272 } v2 __attribute__ ((packed));
273 } __attribute__ ((packed));
242} __attribute__ ((packed)); 274} __attribute__ ((packed));
243 275
276#define P54_TX_CONTROL_CHANNEL_V1_LEN (sizeof(struct p54_tx_control_channel)-12)
277#define P54_TX_CONTROL_CHANNEL_V2_LEN (sizeof(struct p54_tx_control_channel))
278
244struct p54_tx_control_led { 279struct p54_tx_control_led {
245 __le16 mode; 280 __le16 mode;
246 __le16 led_temporary; 281 __le16 led_temporary;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index e9db4495c626..1594786205f8 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -72,8 +72,6 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
72 P54P_WRITE(ctrl_stat, reg); 72 P54P_WRITE(ctrl_stat, reg);
73 wmb(); 73 wmb();
74 74
75 mdelay(50);
76
77 err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev); 75 err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev);
78 if (err) { 76 if (err) {
79 printk(KERN_ERR "%s (p54pci): cannot find firmware " 77 printk(KERN_ERR "%s (p54pci): cannot find firmware "
@@ -81,7 +79,11 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
81 return err; 79 return err;
82 } 80 }
83 81
84 p54_parse_firmware(dev, fw_entry); 82 err = p54_parse_firmware(dev, fw_entry);
83 if (err) {
84 release_firmware(fw_entry);
85 return err;
86 }
85 87
86 data = (__le32 *) fw_entry->data; 88 data = (__le32 *) fw_entry->data;
87 remains = fw_entry->size; 89 remains = fw_entry->size;
@@ -122,120 +124,10 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
122 wmb(); 124 wmb();
123 udelay(10); 125 udelay(10);
124 126
125 return 0; 127 /* wait for the firmware to boot properly */
126}
127
128static irqreturn_t p54p_simple_interrupt(int irq, void *dev_id)
129{
130 struct p54p_priv *priv = (struct p54p_priv *) dev_id;
131 __le32 reg;
132
133 reg = P54P_READ(int_ident);
134 P54P_WRITE(int_ack, reg);
135
136 if (reg & P54P_READ(int_enable))
137 complete(&priv->boot_comp);
138
139 return IRQ_HANDLED;
140}
141
142static int p54p_read_eeprom(struct ieee80211_hw *dev)
143{
144 struct p54p_priv *priv = dev->priv;
145 struct p54p_ring_control *ring_control = priv->ring_control;
146 int err;
147 struct p54_control_hdr *hdr;
148 void *eeprom;
149 dma_addr_t rx_mapping, tx_mapping;
150 u16 alen;
151
152 init_completion(&priv->boot_comp);
153 err = request_irq(priv->pdev->irq, &p54p_simple_interrupt,
154 IRQF_SHARED, "p54pci", priv);
155 if (err) {
156 printk(KERN_ERR "%s (p54pci): failed to register IRQ handler\n",
157 pci_name(priv->pdev));
158 return err;
159 }
160
161 eeprom = kmalloc(0x2010 + EEPROM_READBACK_LEN, GFP_KERNEL);
162 if (!eeprom) {
163 printk(KERN_ERR "%s (p54pci): no memory for eeprom!\n",
164 pci_name(priv->pdev));
165 err = -ENOMEM;
166 goto out;
167 }
168
169 memset(ring_control, 0, sizeof(*ring_control));
170 P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma));
171 P54P_READ(ring_control_base);
172 udelay(10);
173
174 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT));
175 P54P_READ(int_enable);
176 udelay(10);
177
178 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
179
180 if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
181 printk(KERN_ERR "%s (p54pci): Cannot boot firmware!\n",
182 pci_name(priv->pdev));
183 err = -EINVAL;
184 goto out;
185 }
186
187 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE));
188 P54P_READ(int_enable);
189
190 hdr = eeprom + 0x2010;
191 p54_fill_eeprom_readback(hdr);
192 hdr->req_id = cpu_to_le32(priv->common.rx_start);
193
194 rx_mapping = pci_map_single(priv->pdev, eeprom,
195 0x2010, PCI_DMA_FROMDEVICE);
196 tx_mapping = pci_map_single(priv->pdev, (void *)hdr,
197 EEPROM_READBACK_LEN, PCI_DMA_TODEVICE);
198
199 ring_control->rx_mgmt[0].host_addr = cpu_to_le32(rx_mapping);
200 ring_control->rx_mgmt[0].len = cpu_to_le16(0x2010);
201 ring_control->tx_data[0].host_addr = cpu_to_le32(tx_mapping);
202 ring_control->tx_data[0].device_addr = hdr->req_id;
203 ring_control->tx_data[0].len = cpu_to_le16(EEPROM_READBACK_LEN);
204
205 ring_control->host_idx[2] = cpu_to_le32(1);
206 ring_control->host_idx[1] = cpu_to_le32(1);
207
208 wmb();
209 mdelay(100); 128 mdelay(100);
210 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
211 129
212 wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ); 130 return 0;
213 wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ);
214
215 pci_unmap_single(priv->pdev, tx_mapping,
216 EEPROM_READBACK_LEN, PCI_DMA_TODEVICE);
217 pci_unmap_single(priv->pdev, rx_mapping,
218 0x2010, PCI_DMA_FROMDEVICE);
219
220 alen = le16_to_cpu(ring_control->rx_mgmt[0].len);
221 if (le32_to_cpu(ring_control->device_idx[2]) != 1 ||
222 alen < 0x10) {
223 printk(KERN_ERR "%s (p54pci): Cannot read eeprom!\n",
224 pci_name(priv->pdev));
225 err = -EINVAL;
226 goto out;
227 }
228
229 p54_parse_eeprom(dev, (u8 *)eeprom + 0x10, alen - 0x10);
230
231 out:
232 kfree(eeprom);
233 P54P_WRITE(int_enable, cpu_to_le32(0));
234 P54P_READ(int_enable);
235 udelay(10);
236 free_irq(priv->pdev->irq, priv);
237 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
238 return err;
239} 131}
240 132
241static void p54p_refill_rx_ring(struct ieee80211_hw *dev, 133static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
@@ -258,17 +150,17 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
258 if (!desc->host_addr) { 150 if (!desc->host_addr) {
259 struct sk_buff *skb; 151 struct sk_buff *skb;
260 dma_addr_t mapping; 152 dma_addr_t mapping;
261 skb = dev_alloc_skb(MAX_RX_SIZE); 153 skb = dev_alloc_skb(priv->common.rx_mtu + 32);
262 if (!skb) 154 if (!skb)
263 break; 155 break;
264 156
265 mapping = pci_map_single(priv->pdev, 157 mapping = pci_map_single(priv->pdev,
266 skb_tail_pointer(skb), 158 skb_tail_pointer(skb),
267 MAX_RX_SIZE, 159 priv->common.rx_mtu + 32,
268 PCI_DMA_FROMDEVICE); 160 PCI_DMA_FROMDEVICE);
269 desc->host_addr = cpu_to_le32(mapping); 161 desc->host_addr = cpu_to_le32(mapping);
270 desc->device_addr = 0; // FIXME: necessary? 162 desc->device_addr = 0; // FIXME: necessary?
271 desc->len = cpu_to_le16(MAX_RX_SIZE); 163 desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
272 desc->flags = 0; 164 desc->flags = 0;
273 rx_buf[i] = skb; 165 rx_buf[i] = skb;
274 } 166 }
@@ -301,20 +193,23 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
301 len = le16_to_cpu(desc->len); 193 len = le16_to_cpu(desc->len);
302 skb = rx_buf[i]; 194 skb = rx_buf[i];
303 195
304 if (!skb) 196 if (!skb) {
197 i++;
198 i %= ring_limit;
305 continue; 199 continue;
306 200 }
307 skb_put(skb, len); 201 skb_put(skb, len);
308 202
309 if (p54_rx(dev, skb)) { 203 if (p54_rx(dev, skb)) {
310 pci_unmap_single(priv->pdev, 204 pci_unmap_single(priv->pdev,
311 le32_to_cpu(desc->host_addr), 205 le32_to_cpu(desc->host_addr),
312 MAX_RX_SIZE, PCI_DMA_FROMDEVICE); 206 priv->common.rx_mtu + 32,
207 PCI_DMA_FROMDEVICE);
313 rx_buf[i] = NULL; 208 rx_buf[i] = NULL;
314 desc->host_addr = 0; 209 desc->host_addr = 0;
315 } else { 210 } else {
316 skb_trim(skb, 0); 211 skb_trim(skb, 0);
317 desc->len = cpu_to_le16(MAX_RX_SIZE); 212 desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
318 } 213 }
319 214
320 i++; 215 i++;
@@ -466,6 +361,11 @@ static int p54p_open(struct ieee80211_hw *dev)
466 } 361 }
467 362
468 memset(priv->ring_control, 0, sizeof(*priv->ring_control)); 363 memset(priv->ring_control, 0, sizeof(*priv->ring_control));
364 err = p54p_upload_firmware(dev);
365 if (err) {
366 free_irq(priv->pdev->irq, dev);
367 return err;
368 }
469 priv->rx_idx_data = priv->tx_idx_data = 0; 369 priv->rx_idx_data = priv->tx_idx_data = 0;
470 priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0; 370 priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0;
471 371
@@ -475,8 +375,6 @@ static int p54p_open(struct ieee80211_hw *dev)
475 p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt, 375 p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt,
476 ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt); 376 ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt);
477 377
478 p54p_upload_firmware(dev);
479
480 P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma)); 378 P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma));
481 P54P_READ(ring_control_base); 379 P54P_READ(ring_control_base);
482 wmb(); 380 wmb();
@@ -532,7 +430,8 @@ static void p54p_stop(struct ieee80211_hw *dev)
532 if (desc->host_addr) 430 if (desc->host_addr)
533 pci_unmap_single(priv->pdev, 431 pci_unmap_single(priv->pdev,
534 le32_to_cpu(desc->host_addr), 432 le32_to_cpu(desc->host_addr),
535 MAX_RX_SIZE, PCI_DMA_FROMDEVICE); 433 priv->common.rx_mtu + 32,
434 PCI_DMA_FROMDEVICE);
536 kfree_skb(priv->rx_buf_data[i]); 435 kfree_skb(priv->rx_buf_data[i]);
537 priv->rx_buf_data[i] = NULL; 436 priv->rx_buf_data[i] = NULL;
538 } 437 }
@@ -542,7 +441,8 @@ static void p54p_stop(struct ieee80211_hw *dev)
542 if (desc->host_addr) 441 if (desc->host_addr)
543 pci_unmap_single(priv->pdev, 442 pci_unmap_single(priv->pdev,
544 le32_to_cpu(desc->host_addr), 443 le32_to_cpu(desc->host_addr),
545 MAX_RX_SIZE, PCI_DMA_FROMDEVICE); 444 priv->common.rx_mtu + 32,
445 PCI_DMA_FROMDEVICE);
546 kfree_skb(priv->rx_buf_mgmt[i]); 446 kfree_skb(priv->rx_buf_mgmt[i]);
547 priv->rx_buf_mgmt[i] = NULL; 447 priv->rx_buf_mgmt[i] = NULL;
548 } 448 }
@@ -649,16 +549,6 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
649 err = -ENOMEM; 549 err = -ENOMEM;
650 goto err_iounmap; 550 goto err_iounmap;
651 } 551 }
652 memset(priv->ring_control, 0, sizeof(*priv->ring_control));
653
654 err = p54p_upload_firmware(dev);
655 if (err)
656 goto err_free_desc;
657
658 err = p54p_read_eeprom(dev);
659 if (err)
660 goto err_free_desc;
661
662 priv->common.open = p54p_open; 552 priv->common.open = p54p_open;
663 priv->common.stop = p54p_stop; 553 priv->common.stop = p54p_stop;
664 priv->common.tx = p54p_tx; 554 priv->common.tx = p54p_tx;
@@ -666,6 +556,12 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
666 spin_lock_init(&priv->lock); 556 spin_lock_init(&priv->lock);
667 tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); 557 tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev);
668 558
559 p54p_open(dev);
560 err = p54_read_eeprom(dev);
561 p54p_stop(dev);
562 if (err)
563 goto err_free_desc;
564
669 err = ieee80211_register_hw(dev); 565 err = ieee80211_register_hw(dev);
670 if (err) { 566 if (err) {
671 printk(KERN_ERR "%s (p54pci): Cannot register netdevice\n", 567 printk(KERN_ERR "%s (p54pci): Cannot register netdevice\n",
@@ -673,11 +569,6 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
673 goto err_free_common; 569 goto err_free_common;
674 } 570 }
675 571
676 printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
677 wiphy_name(dev->wiphy),
678 print_mac(mac, dev->wiphy->perm_addr),
679 priv->common.version);
680
681 return 0; 572 return 0;
682 573
683 err_free_common: 574 err_free_common:
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 8a420df605af..7444f3729779 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -91,11 +91,16 @@ static void p54u_rx_cb(struct urb *urb)
91 91
92 skb_unlink(skb, &priv->rx_queue); 92 skb_unlink(skb, &priv->rx_queue);
93 skb_put(skb, urb->actual_length); 93 skb_put(skb, urb->actual_length);
94 if (!priv->hw_type) 94
95 skb_pull(skb, sizeof(struct net2280_tx_hdr)); 95 if (priv->hw_type == P54U_NET2280)
96 skb_pull(skb, priv->common.tx_hdr_len);
97 if (priv->common.fw_interface == FW_LM87) {
98 skb_pull(skb, 4);
99 skb_put(skb, 4);
100 }
96 101
97 if (p54_rx(dev, skb)) { 102 if (p54_rx(dev, skb)) {
98 skb = dev_alloc_skb(MAX_RX_SIZE); 103 skb = dev_alloc_skb(priv->common.rx_mtu + 32);
99 if (unlikely(!skb)) { 104 if (unlikely(!skb)) {
100 usb_free_urb(urb); 105 usb_free_urb(urb);
101 /* TODO check rx queue length and refill *somewhere* */ 106 /* TODO check rx queue length and refill *somewhere* */
@@ -109,9 +114,12 @@ static void p54u_rx_cb(struct urb *urb)
109 urb->context = skb; 114 urb->context = skb;
110 skb_queue_tail(&priv->rx_queue, skb); 115 skb_queue_tail(&priv->rx_queue, skb);
111 } else { 116 } else {
112 if (!priv->hw_type) 117 if (priv->hw_type == P54U_NET2280)
113 skb_push(skb, sizeof(struct net2280_tx_hdr)); 118 skb_push(skb, priv->common.tx_hdr_len);
114 119 if (priv->common.fw_interface == FW_LM87) {
120 skb_push(skb, 4);
121 skb_put(skb, 4);
122 }
115 skb_reset_tail_pointer(skb); 123 skb_reset_tail_pointer(skb);
116 skb_trim(skb, 0); 124 skb_trim(skb, 0);
117 if (urb->transfer_buffer != skb_tail_pointer(skb)) { 125 if (urb->transfer_buffer != skb_tail_pointer(skb)) {
@@ -145,7 +153,7 @@ static int p54u_init_urbs(struct ieee80211_hw *dev)
145 struct p54u_rx_info *info; 153 struct p54u_rx_info *info;
146 154
147 while (skb_queue_len(&priv->rx_queue) < 32) { 155 while (skb_queue_len(&priv->rx_queue) < 32) {
148 skb = __dev_alloc_skb(MAX_RX_SIZE, GFP_KERNEL); 156 skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
149 if (!skb) 157 if (!skb)
150 break; 158 break;
151 entry = usb_alloc_urb(0, GFP_KERNEL); 159 entry = usb_alloc_urb(0, GFP_KERNEL);
@@ -153,7 +161,10 @@ static int p54u_init_urbs(struct ieee80211_hw *dev)
153 kfree_skb(skb); 161 kfree_skb(skb);
154 break; 162 break;
155 } 163 }
156 usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), skb_tail_pointer(skb), MAX_RX_SIZE, p54u_rx_cb, skb); 164 usb_fill_bulk_urb(entry, priv->udev,
165 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
166 skb_tail_pointer(skb),
167 priv->common.rx_mtu + 32, p54u_rx_cb, skb);
157 info = (struct p54u_rx_info *) skb->cb; 168 info = (struct p54u_rx_info *) skb->cb;
158 info->urb = entry; 169 info->urb = entry;
159 info->dev = dev; 170 info->dev = dev;
@@ -207,6 +218,42 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
207 usb_submit_urb(data_urb, GFP_ATOMIC); 218 usb_submit_urb(data_urb, GFP_ATOMIC);
208} 219}
209 220
221__le32 p54u_lm87_chksum(const u32 *data, size_t length)
222{
223 __le32 chk = 0;
224
225 length >>= 2;
226 while (length--) {
227 chk ^= cpu_to_le32(*data++);
228 chk = (chk >> 5) ^ (chk << 3);
229 }
230
231 return chk;
232}
233
234static void p54u_tx_lm87(struct ieee80211_hw *dev,
235 struct p54_control_hdr *data,
236 size_t len, int free_on_tx)
237{
238 struct p54u_priv *priv = dev->priv;
239 struct urb *data_urb;
240 struct lm87_tx_hdr *hdr = (void *)data - sizeof(*hdr);
241
242 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
243 if (!data_urb)
244 return;
245
246 hdr->chksum = p54u_lm87_chksum((u32 *)data, len);
247 hdr->device_addr = data->req_id;
248
249 usb_fill_bulk_urb(data_urb, priv->udev,
250 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr,
251 len + sizeof(*hdr), free_on_tx ? p54u_tx_free_cb : p54u_tx_cb,
252 dev);
253
254 usb_submit_urb(data_urb, GFP_ATOMIC);
255}
256
210static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data, 257static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
211 size_t len, int free_on_tx) 258 size_t len, int free_on_tx)
212{ 259{
@@ -312,73 +359,6 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
312 data, len, &alen, 2000); 359 data, len, &alen, 2000);
313} 360}
314 361
315static int p54u_read_eeprom(struct ieee80211_hw *dev)
316{
317 struct p54u_priv *priv = dev->priv;
318 void *buf;
319 struct p54_control_hdr *hdr;
320 int err, alen;
321 size_t offset = priv->hw_type ? 0x10 : 0x20;
322
323 buf = kmalloc(0x2020, GFP_KERNEL);
324 if (!buf) {
325 printk(KERN_ERR "p54usb: cannot allocate memory for "
326 "eeprom readback!\n");
327 return -ENOMEM;
328 }
329
330 if (priv->hw_type) {
331 *((u32 *) buf) = priv->common.rx_start;
332 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
333 if (err) {
334 printk(KERN_ERR "p54usb: addr send failed\n");
335 goto fail;
336 }
337 } else {
338 struct net2280_reg_write *reg = buf;
339 reg->port = cpu_to_le16(NET2280_DEV_U32);
340 reg->addr = cpu_to_le32(P54U_DEV_BASE);
341 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
342 err = p54u_bulk_msg(priv, P54U_PIPE_DEV, buf, sizeof(*reg));
343 if (err) {
344 printk(KERN_ERR "p54usb: dev_int send failed\n");
345 goto fail;
346 }
347 }
348
349 hdr = buf + priv->common.tx_hdr_len;
350 p54_fill_eeprom_readback(hdr);
351 hdr->req_id = cpu_to_le32(priv->common.rx_start);
352 if (priv->common.tx_hdr_len) {
353 struct net2280_tx_hdr *tx_hdr = buf;
354 tx_hdr->device_addr = hdr->req_id;
355 tx_hdr->len = cpu_to_le16(EEPROM_READBACK_LEN);
356 }
357
358 /* we can just pretend to send 0x2000 bytes of nothing in the headers */
359 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf,
360 EEPROM_READBACK_LEN + priv->common.tx_hdr_len);
361 if (err) {
362 printk(KERN_ERR "p54usb: eeprom req send failed\n");
363 goto fail;
364 }
365
366 err = usb_bulk_msg(priv->udev,
367 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
368 buf, 0x2020, &alen, 1000);
369 if (!err && alen > offset) {
370 p54_parse_eeprom(dev, (u8 *)buf + offset, alen - offset);
371 } else {
372 printk(KERN_ERR "p54usb: eeprom read failed!\n");
373 err = -EINVAL;
374 goto fail;
375 }
376
377 fail:
378 kfree(buf);
379 return err;
380}
381
382static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) 362static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
383{ 363{
384 static char start_string[] = "~~~~<\r"; 364 static char start_string[] = "~~~~<\r";
@@ -412,7 +392,9 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
412 goto err_req_fw_failed; 392 goto err_req_fw_failed;
413 } 393 }
414 394
415 p54_parse_firmware(dev, fw_entry); 395 err = p54_parse_firmware(dev, fw_entry);
396 if (err)
397 goto err_upload_failed;
416 398
417 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size); 399 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
418 strcpy(buf, start_string); 400 strcpy(buf, start_string);
@@ -549,7 +531,12 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
549 return err; 531 return err;
550 } 532 }
551 533
552 p54_parse_firmware(dev, fw_entry); 534 err = p54_parse_firmware(dev, fw_entry);
535 if (err) {
536 kfree(buf);
537 release_firmware(fw_entry);
538 return err;
539 }
553 540
554#define P54U_WRITE(type, addr, data) \ 541#define P54U_WRITE(type, addr, data) \
555 do {\ 542 do {\
@@ -833,49 +820,40 @@ static int __devinit p54u_probe(struct usb_interface *intf,
833 } 820 }
834 } 821 }
835 priv->common.open = p54u_open; 822 priv->common.open = p54u_open;
836 823 priv->common.stop = p54u_stop;
837 if (recognized_pipes < P54U_PIPE_NUMBER) { 824 if (recognized_pipes < P54U_PIPE_NUMBER) {
838 priv->hw_type = P54U_3887; 825 priv->hw_type = P54U_3887;
839 priv->common.tx = p54u_tx_3887; 826 err = p54u_upload_firmware_3887(dev);
827 if (priv->common.fw_interface == FW_LM87) {
828 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
829 priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
830 priv->common.tx = p54u_tx_lm87;
831 } else
832 priv->common.tx = p54u_tx_3887;
840 } else { 833 } else {
834 priv->hw_type = P54U_NET2280;
841 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr); 835 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
842 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr); 836 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
843 priv->common.tx = p54u_tx_net2280; 837 priv->common.tx = p54u_tx_net2280;
844 }
845 priv->common.stop = p54u_stop;
846
847 if (priv->hw_type)
848 err = p54u_upload_firmware_3887(dev);
849 else
850 err = p54u_upload_firmware_net2280(dev); 838 err = p54u_upload_firmware_net2280(dev);
839 }
851 if (err) 840 if (err)
852 goto err_free_dev; 841 goto err_free_dev;
853 842
854 err = p54u_read_eeprom(dev); 843 skb_queue_head_init(&priv->rx_queue);
844
845 p54u_open(dev);
846 err = p54_read_eeprom(dev);
847 p54u_stop(dev);
855 if (err) 848 if (err)
856 goto err_free_dev; 849 goto err_free_dev;
857 850
858 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
859 u8 perm_addr[ETH_ALEN];
860
861 printk(KERN_WARNING "p54usb: Invalid hwaddr! Using randomly generated MAC addr\n");
862 random_ether_addr(perm_addr);
863 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
864 }
865
866 skb_queue_head_init(&priv->rx_queue);
867
868 err = ieee80211_register_hw(dev); 851 err = ieee80211_register_hw(dev);
869 if (err) { 852 if (err) {
870 printk(KERN_ERR "p54usb: Cannot register netdevice\n"); 853 printk(KERN_ERR "p54usb: Cannot register netdevice\n");
871 goto err_free_dev; 854 goto err_free_dev;
872 } 855 }
873 856
874 printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
875 wiphy_name(dev->wiphy),
876 print_mac(mac, dev->wiphy->perm_addr),
877 priv->common.version);
878
879 return 0; 857 return 0;
880 858
881 err_free_dev: 859 err_free_dev:
diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h
index 1baaff058c5a..5b8fe91379c3 100644
--- a/drivers/net/wireless/p54/p54usb.h
+++ b/drivers/net/wireless/p54/p54usb.h
@@ -72,6 +72,11 @@ struct net2280_tx_hdr {
72 u8 padding[8]; 72 u8 padding[8];
73} __attribute__((packed)); 73} __attribute__((packed));
74 74
75struct lm87_tx_hdr {
76 __le32 device_addr;
77 __le32 chksum;
78} __attribute__((packed));
79
75/* Some flags for the isl hardware registers controlling DMA inside the 80/* Some flags for the isl hardware registers controlling DMA inside the
76 * chip */ 81 * chip */
77#define ISL38XX_DMA_STATUS_DONE 0x00000001 82#define ISL38XX_DMA_STATUS_DONE 0x00000001
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 369b0b2d8643..2f3bfc606880 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1052,6 +1052,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1052 */ 1052 */
1053 rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); 1053 rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf);
1054 1054
1055 rt2x00dev->hw->wiphy->interface_modes =
1056 BIT(NL80211_IFTYPE_AP) |
1057 BIT(NL80211_IFTYPE_STATION) |
1058 BIT(NL80211_IFTYPE_ADHOC);
1059
1055 /* 1060 /*
1056 * Let the driver probe the device to detect the capabilities. 1061 * Let the driver probe the device to detect the capabilities.
1057 */ 1062 */
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 060a26505358..8a42bfa6d4f0 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -1184,6 +1184,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1184 dev->max_signal = 65; 1184 dev->max_signal = 65;
1185 } 1185 }
1186 1186
1187 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1188
1187 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) 1189 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
1188 printk(KERN_INFO "rtl8187: inconsistency between id with OEM" 1190 printk(KERN_INFO "rtl8187: inconsistency between id with OEM"
1189 " info!\n"); 1191 " info!\n");
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 4d7b98b05030..e019102b2285 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -937,6 +937,11 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
937 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 937 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
938 IEEE80211_HW_SIGNAL_DB; 938 IEEE80211_HW_SIGNAL_DB;
939 939
940 hw->wiphy->interface_modes =
941 BIT(NL80211_IFTYPE_MESH_POINT) |
942 BIT(NL80211_IFTYPE_STATION) |
943 BIT(NL80211_IFTYPE_ADHOC);
944
940 hw->max_signal = 100; 945 hw->max_signal = 100;
941 hw->queues = 1; 946 hw->queues = 1;
942 hw->extra_tx_headroom = sizeof(struct zd_ctrlset); 947 hw->extra_tx_headroom = sizeof(struct zd_ctrlset);
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 0c1147de3ec7..5e51f4e7600b 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -210,6 +210,10 @@ enum nl80211_commands {
210 * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from 210 * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from
211 * association request when used with NL80211_CMD_NEW_STATION) 211 * association request when used with NL80211_CMD_NEW_STATION)
212 * 212 *
213 * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all
214 * supported interface types, each a flag attribute with the number
215 * of the interface mode.
216 *
213 * @NL80211_ATTR_MAX: highest attribute number currently defined 217 * @NL80211_ATTR_MAX: highest attribute number currently defined
214 * @__NL80211_ATTR_AFTER_LAST: internal use 218 * @__NL80211_ATTR_AFTER_LAST: internal use
215 */ 219 */
@@ -259,6 +263,8 @@ enum nl80211_attrs {
259 263
260 NL80211_ATTR_HT_CAPABILITY, 264 NL80211_ATTR_HT_CAPABILITY,
261 265
266 NL80211_ATTR_SUPPORTED_IFTYPES,
267
262 /* add attributes here, update the policy in nl80211.c */ 268 /* add attributes here, update the policy in nl80211.c */
263 269
264 __NL80211_ATTR_AFTER_LAST, 270 __NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/wireless.h b/include/net/wireless.h
index 9324f8dd183e..1dc8ec3daa2f 100644
--- a/include/net/wireless.h
+++ b/include/net/wireless.h
@@ -185,6 +185,9 @@ struct wiphy {
185 /* permanent MAC address */ 185 /* permanent MAC address */
186 u8 perm_addr[ETH_ALEN]; 186 u8 perm_addr[ETH_ALEN];
187 187
188 /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
189 u16 interface_modes;
190
188 /* If multiple wiphys are registered and you're handed e.g. 191 /* If multiple wiphys are registered and you're handed e.g.
189 * a regular netdev with assigned ieee80211_ptr, you won't 192 * a regular netdev with assigned ieee80211_ptr, you won't
190 * know whether it points to a wiphy your driver has registered 193 * know whether it points to a wiphy your driver has registered
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 638b75f36e23..396cfb2d0f46 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1675,6 +1675,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1675 } 1675 }
1676 } 1676 }
1677 1677
1678 /* if low-level driver supports AP, we also support VLAN */
1679 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP))
1680 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
1681
1682 /* mac80211 always supports monitor */
1683 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
1684
1678 result = wiphy_register(local->hw.wiphy); 1685 result = wiphy_register(local->hw.wiphy);
1679 if (result < 0) 1686 if (result < 0)
1680 return result; 1687 return result;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7d53382f1a5b..c396c3522f7b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2557,6 +2557,33 @@ u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
2557 return supp_rates; 2557 return supp_rates;
2558} 2558}
2559 2559
2560static u64 ieee80211_sta_get_mandatory_rates(struct ieee80211_local *local,
2561 enum ieee80211_band band)
2562{
2563 struct ieee80211_supported_band *sband;
2564 struct ieee80211_rate *bitrates;
2565 u64 mandatory_rates;
2566 enum ieee80211_rate_flags mandatory_flag;
2567 int i;
2568
2569 sband = local->hw.wiphy->bands[band];
2570 if (!sband) {
2571 WARN_ON(1);
2572 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2573 }
2574
2575 if (band == IEEE80211_BAND_2GHZ)
2576 mandatory_flag = IEEE80211_RATE_MANDATORY_B;
2577 else
2578 mandatory_flag = IEEE80211_RATE_MANDATORY_A;
2579
2580 bitrates = sband->bitrates;
2581 mandatory_rates = 0;
2582 for (i = 0; i < sband->n_bitrates; i++)
2583 if (bitrates[i].flags & mandatory_flag)
2584 mandatory_rates |= BIT(i);
2585 return mandatory_rates;
2586}
2560 2587
2561static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 2588static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2562 struct ieee80211_mgmt *mgmt, 2589 struct ieee80211_mgmt *mgmt,
@@ -2568,9 +2595,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2568 int freq, clen; 2595 int freq, clen;
2569 struct ieee80211_sta_bss *bss; 2596 struct ieee80211_sta_bss *bss;
2570 struct sta_info *sta; 2597 struct sta_info *sta;
2571 u64 beacon_timestamp, rx_timestamp;
2572 struct ieee80211_channel *channel; 2598 struct ieee80211_channel *channel;
2599 u64 beacon_timestamp, rx_timestamp;
2600 u64 supp_rates = 0;
2573 bool beacon = ieee80211_is_beacon(mgmt->frame_control); 2601 bool beacon = ieee80211_is_beacon(mgmt->frame_control);
2602 enum ieee80211_band band = rx_status->band;
2574 DECLARE_MAC_BUF(mac); 2603 DECLARE_MAC_BUF(mac);
2575 DECLARE_MAC_BUF(mac2); 2604 DECLARE_MAC_BUF(mac2);
2576 2605
@@ -2578,30 +2607,41 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2578 2607
2579 if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id && 2608 if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id &&
2580 elems->mesh_config && mesh_matches_local(elems, sdata)) { 2609 elems->mesh_config && mesh_matches_local(elems, sdata)) {
2581 u64 rates = ieee80211_sta_get_rates(local, elems, 2610 supp_rates = ieee80211_sta_get_rates(local, elems, band);
2582 rx_status->band);
2583 2611
2584 mesh_neighbour_update(mgmt->sa, rates, sdata, 2612 mesh_neighbour_update(mgmt->sa, supp_rates, sdata,
2585 mesh_peer_accepts_plinks(elems)); 2613 mesh_peer_accepts_plinks(elems));
2586 } 2614 }
2587 2615
2588 rcu_read_lock(); 2616 rcu_read_lock();
2589 2617
2590 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates && 2618 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates &&
2591 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && 2619 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
2592 (sta = sta_info_get(local, mgmt->sa))) { 2620
2593 u64 prev_rates; 2621 supp_rates = ieee80211_sta_get_rates(local, elems, band);
2594 u64 supp_rates = ieee80211_sta_get_rates(local, elems, 2622
2595 rx_status->band); 2623 sta = sta_info_get(local, mgmt->sa);
2596 2624 if (sta) {
2597 prev_rates = sta->supp_rates[rx_status->band]; 2625 u64 prev_rates;
2598 sta->supp_rates[rx_status->band] &= supp_rates; 2626
2599 if (sta->supp_rates[rx_status->band] == 0) { 2627 prev_rates = sta->supp_rates[band];
2600 /* No matching rates - this should not really happen. 2628 /* make sure mandatory rates are always added */
2601 * Make sure that at least one rate is marked 2629 sta->supp_rates[band] = supp_rates |
2602 * supported to avoid issues with TX rate ctrl. */ 2630 ieee80211_sta_get_mandatory_rates(local, band);
2603 sta->supp_rates[rx_status->band] = 2631
2604 sdata->u.sta.supp_rates_bits[rx_status->band]; 2632#ifdef CONFIG_MAC80211_IBSS_DEBUG
2633 if (sta->supp_rates[band] != prev_rates)
2634 printk(KERN_DEBUG "%s: updated supp_rates set "
2635 "for %s based on beacon info (0x%llx | "
2636 "0x%llx -> 0x%llx)\n",
2637 sdata->dev->name, print_mac(mac, sta->addr),
2638 (unsigned long long) prev_rates,
2639 (unsigned long long) supp_rates,
2640 (unsigned long long) sta->supp_rates[band]);
2641#endif
2642 } else {
2643 ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid,
2644 mgmt->sa, supp_rates);
2605 } 2645 }
2606 } 2646 }
2607 2647
@@ -2683,7 +2723,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2683 bss->supp_rates_len += clen; 2723 bss->supp_rates_len += clen;
2684 } 2724 }
2685 2725
2686 bss->band = rx_status->band; 2726 bss->band = band;
2687 2727
2688 bss->timestamp = beacon_timestamp; 2728 bss->timestamp = beacon_timestamp;
2689 bss->last_update = jiffies; 2729 bss->last_update = jiffies;
@@ -2738,7 +2778,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2738 * e.g: at 1 MBit that means mactime is 192 usec earlier 2778 * e.g: at 1 MBit that means mactime is 192 usec earlier
2739 * (=24 bytes * 8 usecs/byte) than the beacon timestamp. 2779 * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
2740 */ 2780 */
2741 int rate = local->hw.wiphy->bands[rx_status->band]-> 2781 int rate = local->hw.wiphy->bands[band]->
2742 bitrates[rx_status->rate_idx].bitrate; 2782 bitrates[rx_status->rate_idx].bitrate;
2743 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); 2783 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
2744 } else if (local && local->ops && local->ops->get_tsf) 2784 } else if (local && local->ops && local->ops->get_tsf)
@@ -2766,7 +2806,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2766 ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); 2806 ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
2767 ieee80211_ibss_add_sta(sdata, NULL, 2807 ieee80211_ibss_add_sta(sdata, NULL,
2768 mgmt->bssid, mgmt->sa, 2808 mgmt->bssid, mgmt->sa,
2769 BIT(rx_status->rate_idx)); 2809 supp_rates);
2770 } 2810 }
2771 } 2811 }
2772 2812
@@ -3032,7 +3072,6 @@ void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *
3032 kfree_skb(skb); 3072 kfree_skb(skb);
3033} 3073}
3034 3074
3035
3036static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 3075static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3037 struct sk_buff *skb) 3076 struct sk_buff *skb)
3038{ 3077{
@@ -4316,10 +4355,9 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
4316 4355
4317 set_sta_flags(sta, WLAN_STA_AUTHORIZED); 4356 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
4318 4357
4319 if (supp_rates) 4358 /* make sure mandatory rates are always added */
4320 sta->supp_rates[band] = supp_rates; 4359 sta->supp_rates[band] = supp_rates |
4321 else 4360 ieee80211_sta_get_mandatory_rates(local, band);
4322 sta->supp_rates[band] = sdata->u.sta.supp_rates_bits[band];
4323 4361
4324 rate_control_rate_init(sta, local); 4362 rate_control_rate_init(sta, local);
4325 4363
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fd83ef760a37..7e09b30dd393 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1743,10 +1743,6 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1743 if (!bssid) 1743 if (!bssid)
1744 return 0; 1744 return 0;
1745 if (ieee80211_is_beacon(hdr->frame_control)) { 1745 if (ieee80211_is_beacon(hdr->frame_control)) {
1746 if (!rx->sta)
1747 rx->sta = ieee80211_ibss_add_sta(sdata,
1748 rx->skb, bssid, hdr->addr2,
1749 BIT(rx->status->rate_idx));
1750 return 1; 1746 return 1;
1751 } 1747 }
1752 else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { 1748 else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) {
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 109db787ccb7..4a581a5b5766 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -204,6 +204,7 @@ struct sta_ampdu_mlme {
204 * @tx_fragments: number of transmitted MPDUs 204 * @tx_fragments: number of transmitted MPDUs
205 * @txrate_idx: TBD 205 * @txrate_idx: TBD
206 * @last_txrate_idx: TBD 206 * @last_txrate_idx: TBD
207 * @tid_seq: TBD
207 * @wme_tx_queue: TBD 208 * @wme_tx_queue: TBD
208 * @ampdu_mlme: TBD 209 * @ampdu_mlme: TBD
209 * @timer_to_tid: identity mapping to ID timers 210 * @timer_to_tid: identity mapping to ID timers
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f1da0b93bc56..7e995ac06a0c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This is the linux wireless configuration interface. 2 * This is the linux wireless configuration interface.
3 * 3 *
4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6 6
7#include <linux/if.h> 7#include <linux/if.h>
@@ -259,6 +259,13 @@ int wiphy_register(struct wiphy *wiphy)
259 struct ieee80211_supported_band *sband; 259 struct ieee80211_supported_band *sband;
260 bool have_band = false; 260 bool have_band = false;
261 int i; 261 int i;
262 u16 ifmodes = wiphy->interface_modes;
263
264 /* sanity check ifmodes */
265 WARN_ON(!ifmodes);
266 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
267 if (WARN_ON(ifmodes != wiphy->interface_modes))
268 wiphy->interface_modes = ifmodes;
262 269
263 /* sanity check supported bands/channels */ 270 /* sanity check supported bands/channels */
264 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 271 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4d6c02afd6f5..77880ba8b619 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -113,10 +113,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
113 struct nlattr *nl_bands, *nl_band; 113 struct nlattr *nl_bands, *nl_band;
114 struct nlattr *nl_freqs, *nl_freq; 114 struct nlattr *nl_freqs, *nl_freq;
115 struct nlattr *nl_rates, *nl_rate; 115 struct nlattr *nl_rates, *nl_rate;
116 struct nlattr *nl_modes;
116 enum ieee80211_band band; 117 enum ieee80211_band band;
117 struct ieee80211_channel *chan; 118 struct ieee80211_channel *chan;
118 struct ieee80211_rate *rate; 119 struct ieee80211_rate *rate;
119 int i; 120 int i;
121 u16 ifmodes = dev->wiphy.interface_modes;
120 122
121 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); 123 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
122 if (!hdr) 124 if (!hdr)
@@ -125,6 +127,20 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
125 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); 127 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
126 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 128 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
127 129
130 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
131 if (!nl_modes)
132 goto nla_put_failure;
133
134 i = 0;
135 while (ifmodes) {
136 if (ifmodes & 1)
137 NLA_PUT_FLAG(msg, i);
138 ifmodes >>= 1;
139 i++;
140 }
141
142 nla_nest_end(msg, nl_modes);
143
128 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); 144 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
129 if (!nl_bands) 145 if (!nl_bands)
130 goto nla_put_failure; 146 goto nla_put_failure;
@@ -415,7 +431,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
415 ifindex = dev->ifindex; 431 ifindex = dev->ifindex;
416 dev_put(dev); 432 dev_put(dev);
417 433
418 if (!drv->ops->change_virtual_intf) { 434 if (!drv->ops->change_virtual_intf ||
435 !(drv->wiphy.interface_modes & (1 << type))) {
419 err = -EOPNOTSUPP; 436 err = -EOPNOTSUPP;
420 goto unlock; 437 goto unlock;
421 } 438 }
@@ -462,7 +479,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
462 if (IS_ERR(drv)) 479 if (IS_ERR(drv))
463 return PTR_ERR(drv); 480 return PTR_ERR(drv);
464 481
465 if (!drv->ops->add_virtual_intf) { 482 if (!drv->ops->add_virtual_intf ||
483 !(drv->wiphy.interface_modes & (1 << type))) {
466 err = -EOPNOTSUPP; 484 err = -EOPNOTSUPP;
467 goto unlock; 485 goto unlock;
468 } 486 }