diff options
author | Vivek Natarajan <vnatarajan@atheros.com> | 2010-08-18 10:27:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-24 16:32:05 -0400 |
commit | 21cb987914cb5334af78378141efed77505ea987 (patch) | |
tree | 73d725ef440e84a5880ddf648d66dfea811dae71 /drivers/net | |
parent | d99eeb87420a6da1f87064c7fa70bdf299699d90 (diff) |
ath9k_htc: Add support for bluetooth coexistence.
Signed-off-by: Vivek Natarajan <vnatarajan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/btcoex.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hif_usb.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc.h | 42 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 134 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_init.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_main.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_hst.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_hst.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/wmi.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/wmi.h | 1 |
11 files changed, 230 insertions, 22 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 973ae4f49f35..4555e9983903 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -46,6 +46,7 @@ ath9k_htc-y += htc_hst.o \ | |||
46 | htc_drv_txrx.o \ | 46 | htc_drv_txrx.o \ |
47 | htc_drv_main.o \ | 47 | htc_drv_main.o \ |
48 | htc_drv_beacon.o \ | 48 | htc_drv_beacon.o \ |
49 | htc_drv_init.o | 49 | htc_drv_init.o \ |
50 | htc_drv_gpio.o | ||
50 | 51 | ||
51 | obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o | 52 | obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index fb4ac15f3b93..6a92e57fddf0 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c | |||
@@ -168,6 +168,7 @@ EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); | |||
168 | static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) | 168 | static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) |
169 | { | 169 | { |
170 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 170 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
171 | u32 val; | ||
171 | 172 | ||
172 | /* | 173 | /* |
173 | * Program coex mode and weight registers to | 174 | * Program coex mode and weight registers to |
@@ -177,6 +178,12 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) | |||
177 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); | 178 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); |
178 | REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); | 179 | REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); |
179 | 180 | ||
181 | if (AR_SREV_9271(ah)) { | ||
182 | val = REG_READ(ah, 0x50040); | ||
183 | val &= 0xFFFFFEFF; | ||
184 | REG_WRITE(ah, 0x50040, val); | ||
185 | } | ||
186 | |||
180 | REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); | 187 | REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); |
181 | REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); | 188 | REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); |
182 | 189 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 17e7a9a367e7..495f18950ac9 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -920,7 +920,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, | |||
920 | } | 920 | } |
921 | 921 | ||
922 | ret = ath9k_htc_hw_init(hif_dev->htc_handle, | 922 | ret = ath9k_htc_hw_init(hif_dev->htc_handle, |
923 | &hif_dev->udev->dev, hif_dev->device_id); | 923 | &hif_dev->udev->dev, hif_dev->device_id, |
924 | hif_dev->udev->product); | ||
924 | if (ret) { | 925 | if (ret) { |
925 | ret = -EINVAL; | 926 | ret = -EINVAL; |
926 | goto err_htc_hw_init; | 927 | goto err_htc_hw_init; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 43b9e21bc562..75ecf6a30d25 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -316,17 +316,32 @@ struct htc_beacon_config { | |||
316 | u8 dtim_count; | 316 | u8 dtim_count; |
317 | }; | 317 | }; |
318 | 318 | ||
319 | #define OP_INVALID BIT(0) | 319 | struct ath_btcoex { |
320 | #define OP_SCANNING BIT(1) | 320 | u32 bt_priority_cnt; |
321 | #define OP_FULL_RESET BIT(2) | 321 | unsigned long bt_priority_time; |
322 | #define OP_LED_ASSOCIATED BIT(3) | 322 | int bt_stomp_type; /* Types of BT stomping */ |
323 | #define OP_LED_ON BIT(4) | 323 | u32 btcoex_no_stomp; |
324 | #define OP_PREAMBLE_SHORT BIT(5) | 324 | u32 btcoex_period; |
325 | #define OP_PROTECT_ENABLE BIT(6) | 325 | u32 btscan_no_stomp; |
326 | #define OP_ASSOCIATED BIT(7) | 326 | }; |
327 | #define OP_ENABLE_BEACON BIT(8) | 327 | |
328 | #define OP_LED_DEINIT BIT(9) | 328 | void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv); |
329 | #define OP_UNPLUGGED BIT(10) | 329 | void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv); |
330 | void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); | ||
331 | |||
332 | #define OP_INVALID BIT(0) | ||
333 | #define OP_SCANNING BIT(1) | ||
334 | #define OP_FULL_RESET BIT(2) | ||
335 | #define OP_LED_ASSOCIATED BIT(3) | ||
336 | #define OP_LED_ON BIT(4) | ||
337 | #define OP_PREAMBLE_SHORT BIT(5) | ||
338 | #define OP_PROTECT_ENABLE BIT(6) | ||
339 | #define OP_ASSOCIATED BIT(7) | ||
340 | #define OP_ENABLE_BEACON BIT(8) | ||
341 | #define OP_LED_DEINIT BIT(9) | ||
342 | #define OP_UNPLUGGED BIT(10) | ||
343 | #define OP_BT_PRIORITY_DETECTED BIT(11) | ||
344 | #define OP_BT_SCAN BIT(12) | ||
330 | 345 | ||
331 | struct ath9k_htc_priv { | 346 | struct ath9k_htc_priv { |
332 | struct device *dev; | 347 | struct device *dev; |
@@ -391,6 +406,9 @@ struct ath9k_htc_priv { | |||
391 | int cabq; | 406 | int cabq; |
392 | int hwq_map[WME_NUM_AC]; | 407 | int hwq_map[WME_NUM_AC]; |
393 | 408 | ||
409 | struct ath_btcoex btcoex; | ||
410 | struct delayed_work coex_period_work; | ||
411 | struct delayed_work duty_cycle_work; | ||
394 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 412 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
395 | struct ath9k_debug debug; | 413 | struct ath9k_debug debug; |
396 | #endif | 414 | #endif |
@@ -443,7 +461,7 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv); | |||
443 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv); | 461 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv); |
444 | 462 | ||
445 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | 463 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, |
446 | u16 devid); | 464 | u16 devid, char *product); |
447 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); | 465 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); |
448 | #ifdef CONFIG_PM | 466 | #ifdef CONFIG_PM |
449 | int ath9k_htc_resume(struct htc_target *htc_handle); | 467 | int ath9k_htc_resume(struct htc_target *htc_handle); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c new file mode 100644 index 000000000000..50eec9a3b88c --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | |||
@@ -0,0 +1,134 @@ | |||
1 | #include "htc.h" | ||
2 | |||
3 | /******************/ | ||
4 | /* BTCOEX */ | ||
5 | /******************/ | ||
6 | |||
7 | /* | ||
8 | * Detects if there is any priority bt traffic | ||
9 | */ | ||
10 | static void ath_detect_bt_priority(struct ath9k_htc_priv *priv) | ||
11 | { | ||
12 | struct ath_btcoex *btcoex = &priv->btcoex; | ||
13 | struct ath_hw *ah = priv->ah; | ||
14 | |||
15 | if (ath9k_hw_gpio_get(ah, ah->btcoex_hw.btpriority_gpio)) | ||
16 | btcoex->bt_priority_cnt++; | ||
17 | |||
18 | if (time_after(jiffies, btcoex->bt_priority_time + | ||
19 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { | ||
20 | priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); | ||
21 | /* Detect if colocated bt started scanning */ | ||
22 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { | ||
23 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
24 | "BT scan detected"); | ||
25 | priv->op_flags |= (OP_BT_SCAN | | ||
26 | OP_BT_PRIORITY_DETECTED); | ||
27 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | ||
28 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
29 | "BT priority traffic detected"); | ||
30 | priv->op_flags |= OP_BT_PRIORITY_DETECTED; | ||
31 | } | ||
32 | |||
33 | btcoex->bt_priority_cnt = 0; | ||
34 | btcoex->bt_priority_time = jiffies; | ||
35 | } | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * This is the master bt coex work which runs for every | ||
40 | * 45ms, bt traffic will be given priority during 55% of this | ||
41 | * period while wlan gets remaining 45% | ||
42 | */ | ||
43 | static void ath_btcoex_period_work(struct work_struct *work) | ||
44 | { | ||
45 | struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, | ||
46 | coex_period_work.work); | ||
47 | struct ath_btcoex *btcoex = &priv->btcoex; | ||
48 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
49 | u32 timer_period; | ||
50 | bool is_btscan; | ||
51 | int ret; | ||
52 | u8 cmd_rsp, aggr; | ||
53 | |||
54 | ath_detect_bt_priority(priv); | ||
55 | |||
56 | is_btscan = !!(priv->op_flags & OP_BT_SCAN); | ||
57 | |||
58 | aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED; | ||
59 | |||
60 | WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr); | ||
61 | |||
62 | ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : | ||
63 | btcoex->bt_stomp_type); | ||
64 | |||
65 | timer_period = is_btscan ? btcoex->btscan_no_stomp : | ||
66 | btcoex->btcoex_no_stomp; | ||
67 | ieee80211_queue_delayed_work(priv->hw, &priv->duty_cycle_work, | ||
68 | msecs_to_jiffies(timer_period)); | ||
69 | ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, | ||
70 | msecs_to_jiffies(btcoex->btcoex_period)); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Work to time slice between wlan and bt traffic and | ||
75 | * configure weight registers | ||
76 | */ | ||
77 | static void ath_btcoex_duty_cycle_work(struct work_struct *work) | ||
78 | { | ||
79 | struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, | ||
80 | duty_cycle_work.work); | ||
81 | struct ath_hw *ah = priv->ah; | ||
82 | struct ath_btcoex *btcoex = &priv->btcoex; | ||
83 | struct ath_common *common = ath9k_hw_common(ah); | ||
84 | bool is_btscan = priv->op_flags & OP_BT_SCAN; | ||
85 | |||
86 | ath_print(common, ATH_DBG_BTCOEX, | ||
87 | "time slice work for bt and wlan\n"); | ||
88 | |||
89 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | ||
90 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); | ||
91 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | ||
92 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); | ||
93 | } | ||
94 | |||
95 | void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) | ||
96 | { | ||
97 | struct ath_btcoex *btcoex = &priv->btcoex; | ||
98 | |||
99 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; | ||
100 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | ||
101 | btcoex->btcoex_period / 100; | ||
102 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * | ||
103 | btcoex->btcoex_period / 100; | ||
104 | INIT_DELAYED_WORK(&priv->coex_period_work, ath_btcoex_period_work); | ||
105 | INIT_DELAYED_WORK(&priv->duty_cycle_work, ath_btcoex_duty_cycle_work); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * (Re)start btcoex work | ||
110 | */ | ||
111 | |||
112 | void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) | ||
113 | { | ||
114 | struct ath_btcoex *btcoex = &priv->btcoex; | ||
115 | struct ath_hw *ah = priv->ah; | ||
116 | |||
117 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
118 | "Starting btcoex work"); | ||
119 | |||
120 | btcoex->bt_priority_cnt = 0; | ||
121 | btcoex->bt_priority_time = jiffies; | ||
122 | priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); | ||
123 | ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, 0); | ||
124 | } | ||
125 | |||
126 | |||
127 | /* | ||
128 | * Cancel btcoex and bt duty cycle work. | ||
129 | */ | ||
130 | void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) | ||
131 | { | ||
132 | cancel_delayed_work_sync(&priv->coex_period_work); | ||
133 | cancel_delayed_work_sync(&priv->duty_cycle_work); | ||
134 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 2d4279191d7a..695e2b088d10 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -41,6 +41,8 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | |||
41 | .max_power = 20, \ | 41 | .max_power = 20, \ |
42 | } | 42 | } |
43 | 43 | ||
44 | #define ATH_HTC_BTCOEX_PRODUCT_ID "wb193" | ||
45 | |||
44 | static struct ieee80211_channel ath9k_2ghz_channels[] = { | 46 | static struct ieee80211_channel ath9k_2ghz_channels[] = { |
45 | CHAN2G(2412, 0), /* Channel 1 */ | 47 | CHAN2G(2412, 0), /* Channel 1 */ |
46 | CHAN2G(2417, 1), /* Channel 2 */ | 48 | CHAN2G(2417, 1), /* Channel 2 */ |
@@ -605,7 +607,31 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) | |||
605 | priv->ah->opmode = NL80211_IFTYPE_STATION; | 607 | priv->ah->opmode = NL80211_IFTYPE_STATION; |
606 | } | 608 | } |
607 | 609 | ||
608 | static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid) | 610 | static void ath9k_init_btcoex(struct ath9k_htc_priv *priv) |
611 | { | ||
612 | int qnum; | ||
613 | |||
614 | switch (priv->ah->btcoex_hw.scheme) { | ||
615 | case ATH_BTCOEX_CFG_NONE: | ||
616 | break; | ||
617 | case ATH_BTCOEX_CFG_3WIRE: | ||
618 | priv->ah->btcoex_hw.btactive_gpio = 7; | ||
619 | priv->ah->btcoex_hw.btpriority_gpio = 6; | ||
620 | priv->ah->btcoex_hw.wlanactive_gpio = 8; | ||
621 | priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
622 | ath9k_hw_btcoex_init_3wire(priv->ah); | ||
623 | ath_htc_init_btcoex_work(priv); | ||
624 | qnum = priv->hwq_map[WME_AC_BE]; | ||
625 | ath9k_hw_init_btcoex_hw(priv->ah, qnum); | ||
626 | break; | ||
627 | default: | ||
628 | WARN_ON(1); | ||
629 | break; | ||
630 | } | ||
631 | } | ||
632 | |||
633 | static int ath9k_init_priv(struct ath9k_htc_priv *priv, | ||
634 | u16 devid, char *product) | ||
609 | { | 635 | { |
610 | struct ath_hw *ah = NULL; | 636 | struct ath_hw *ah = NULL; |
611 | struct ath_common *common; | 637 | struct ath_common *common; |
@@ -672,6 +698,11 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid) | |||
672 | ath9k_init_channels_rates(priv); | 698 | ath9k_init_channels_rates(priv); |
673 | ath9k_init_misc(priv); | 699 | ath9k_init_misc(priv); |
674 | 700 | ||
701 | if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) { | ||
702 | ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE; | ||
703 | ath9k_init_btcoex(priv); | ||
704 | } | ||
705 | |||
675 | return 0; | 706 | return 0; |
676 | 707 | ||
677 | err_queues: | 708 | err_queues: |
@@ -734,7 +765,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
734 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | 765 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); |
735 | } | 766 | } |
736 | 767 | ||
737 | static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid) | 768 | static int ath9k_init_device(struct ath9k_htc_priv *priv, |
769 | u16 devid, char *product) | ||
738 | { | 770 | { |
739 | struct ieee80211_hw *hw = priv->hw; | 771 | struct ieee80211_hw *hw = priv->hw; |
740 | struct ath_common *common; | 772 | struct ath_common *common; |
@@ -743,7 +775,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid) | |||
743 | struct ath_regulatory *reg; | 775 | struct ath_regulatory *reg; |
744 | 776 | ||
745 | /* Bring up device */ | 777 | /* Bring up device */ |
746 | error = ath9k_init_priv(priv, devid); | 778 | error = ath9k_init_priv(priv, devid, product); |
747 | if (error != 0) | 779 | if (error != 0) |
748 | goto err_init; | 780 | goto err_init; |
749 | 781 | ||
@@ -801,7 +833,7 @@ err_init: | |||
801 | } | 833 | } |
802 | 834 | ||
803 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | 835 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, |
804 | u16 devid) | 836 | u16 devid, char *product) |
805 | { | 837 | { |
806 | struct ieee80211_hw *hw; | 838 | struct ieee80211_hw *hw; |
807 | struct ath9k_htc_priv *priv; | 839 | struct ath9k_htc_priv *priv; |
@@ -835,7 +867,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | |||
835 | /* The device may have been unplugged earlier. */ | 867 | /* The device may have been unplugged earlier. */ |
836 | priv->op_flags &= ~OP_UNPLUGGED; | 868 | priv->op_flags &= ~OP_UNPLUGGED; |
837 | 869 | ||
838 | ret = ath9k_init_device(priv, devid); | 870 | ret = ath9k_init_device(priv, devid, product); |
839 | if (ret) | 871 | if (ret) |
840 | goto err_init; | 872 | goto err_init; |
841 | 873 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 4e345be62435..5e318cb662c6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1210,6 +1210,12 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1210 | 1210 | ||
1211 | ieee80211_wake_queues(hw); | 1211 | ieee80211_wake_queues(hw); |
1212 | 1212 | ||
1213 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { | ||
1214 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
1215 | AR_STOMP_LOW_WLAN_WGHT); | ||
1216 | ath9k_hw_btcoex_enable(ah); | ||
1217 | ath_htc_resume_btcoex_work(priv); | ||
1218 | } | ||
1213 | mutex_unlock(&priv->mutex); | 1219 | mutex_unlock(&priv->mutex); |
1214 | 1220 | ||
1215 | return ret; | 1221 | return ret; |
@@ -1254,6 +1260,12 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1254 | "Monitor interface removed\n"); | 1260 | "Monitor interface removed\n"); |
1255 | } | 1261 | } |
1256 | 1262 | ||
1263 | if (ah->btcoex_hw.enabled) { | ||
1264 | ath9k_hw_btcoex_disable(ah); | ||
1265 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | ||
1266 | ath_htc_cancel_btcoex_work(priv); | ||
1267 | } | ||
1268 | |||
1257 | ath9k_hw_phy_disable(ah); | 1269 | ath9k_hw_phy_disable(ah); |
1258 | ath9k_hw_disable(ah); | 1270 | ath9k_hw_disable(ah); |
1259 | ath9k_hw_configpcipowersave(ah, 1, 1); | 1271 | ath9k_hw_configpcipowersave(ah, 1, 1); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 705c0f342e1c..861ec9269309 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -462,9 +462,9 @@ void ath9k_htc_hw_free(struct htc_target *htc) | |||
462 | } | 462 | } |
463 | 463 | ||
464 | int ath9k_htc_hw_init(struct htc_target *target, | 464 | int ath9k_htc_hw_init(struct htc_target *target, |
465 | struct device *dev, u16 devid) | 465 | struct device *dev, u16 devid, char *product) |
466 | { | 466 | { |
467 | if (ath9k_htc_probe_device(target, dev, devid)) { | 467 | if (ath9k_htc_probe_device(target, dev, devid, product)) { |
468 | printk(KERN_ERR "Failed to initialize the device\n"); | 468 | printk(KERN_ERR "Failed to initialize the device\n"); |
469 | return -ENODEV; | 469 | return -ENODEV; |
470 | } | 470 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index faba6790328b..07b6509d5896 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h | |||
@@ -239,7 +239,7 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, | |||
239 | struct device *dev); | 239 | struct device *dev); |
240 | void ath9k_htc_hw_free(struct htc_target *htc); | 240 | void ath9k_htc_hw_free(struct htc_target *htc); |
241 | int ath9k_htc_hw_init(struct htc_target *target, | 241 | int ath9k_htc_hw_init(struct htc_target *target, |
242 | struct device *dev, u16 devid); | 242 | struct device *dev, u16 devid, char *product); |
243 | void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug); | 243 | void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug); |
244 | 244 | ||
245 | #endif /* HTC_HST_H */ | 245 | #endif /* HTC_HST_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 6260faa658a2..45fe9cac7971 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -85,6 +85,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
85 | return "WMI_TGT_DETACH_CMDID"; | 85 | return "WMI_TGT_DETACH_CMDID"; |
86 | case WMI_TGT_TXQ_ENABLE_CMDID: | 86 | case WMI_TGT_TXQ_ENABLE_CMDID: |
87 | return "WMI_TGT_TXQ_ENABLE_CMDID"; | 87 | return "WMI_TGT_TXQ_ENABLE_CMDID"; |
88 | case WMI_AGGR_LIMIT_CMD: | ||
89 | return "WMI_AGGR_LIMIT_CMD"; | ||
88 | } | 90 | } |
89 | 91 | ||
90 | return "Bogus"; | 92 | return "Bogus"; |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 765db5faa2d3..a0bf857625df 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h | |||
@@ -71,6 +71,7 @@ enum wmi_cmd_id { | |||
71 | WMI_TX_AGGR_ENABLE_CMDID, | 71 | WMI_TX_AGGR_ENABLE_CMDID, |
72 | WMI_TGT_DETACH_CMDID, | 72 | WMI_TGT_DETACH_CMDID, |
73 | WMI_TGT_TXQ_ENABLE_CMDID, | 73 | WMI_TGT_TXQ_ENABLE_CMDID, |
74 | WMI_AGGR_LIMIT_CMD = 0x0026, | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | enum wmi_event_id { | 77 | enum wmi_event_id { |