diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-08-23 07:57:04 -0700 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-25 14:34:19 -0400 |
commit | bee008b78307ccc2e17c7ec152dd2098d5f2e1fa (patch) | |
tree | a66fd8ef5e086df61c5f8e27a575e4877a06c680 /drivers/net/wireless/iwlwifi/iwl-6000.c | |
parent | bd6e2d579949aede258c673caf4b1eb39b95e172 (diff) |
iwlwifi: add bt full concurrency support
Adding the bluetooth full concurrency support for WiFi/BT combo devices.
Driver should configure uCode to operate in "full concurrency" mode (via
LUT) if both conditions are met:
- Antenna Coupling is more than 35dB
- WiFi Channel Inhibition Request is hornored by BT Core
Currently, there is no antenna coupling information provided by uCode;
use module parameter to specified the antenna coupling in dB.
When in "full concurrency" mode, driver need to download different LUT
to uCode while sending bt configuration command; also, driver need to
configure the device operate in 1x1 while in full concurrency mode.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-6000.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-6000.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 9d430987cc6..a4601b58a5d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -201,6 +201,21 @@ static const __le32 iwl6000g2b_def_3w_lookup[12] = { cpu_to_le32(0xf0004000), }; +static const __le32 iwl6000g2b_concurrent_lookup[12] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), +}; + static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) { struct iwl6000g2b_bt_cmd bt_cmd = { @@ -233,11 +248,17 @@ static void iwl6000g2b_send_bt_config(struct iwl_priv *priv) bt_cmd.valid |= IWL6000G2B_BT_ALL_VALID_MSK; } - memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_def_3w_lookup, - sizeof(iwl6000g2b_def_3w_lookup)); + if (priv->bt_full_concurrent) + memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_concurrent_lookup, + sizeof(iwl6000g2b_concurrent_lookup)); + else + memcpy(bt_cmd.bt3_lookup_table, iwl6000g2b_def_3w_lookup, + sizeof(iwl6000g2b_def_3w_lookup)); - IWL_DEBUG_INFO(priv, "BT coex %s\n", - bt_cmd.flags ? "active" : "disabled"); + IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n", + bt_cmd.flags ? "active" : "disabled", + priv->bt_full_concurrent ? + "full concurrency" : "3-wire"); if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); @@ -435,6 +456,7 @@ static void iwl6000g2b_bt_traffic_change_work(struct work_struct *work) static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { + unsigned long flags; struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwl6000g2b_bt_sco_cmd sco_cmd = { .flags = 0 }; @@ -466,6 +488,10 @@ static void iwl6000g2b_bt_coex_profile_notif(struct iwl_priv *priv, iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, sizeof(sco_cmd), &sco_cmd, NULL); } + + spin_lock_irqsave(&priv->lock, flags); + priv->bt_ci_compliance = coex->bt_ci_compliance; + spin_unlock_irqrestore(&priv->lock, flags); } void iwl6000g2b_rx_handler_setup(struct iwl_priv *priv) |