aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-lib.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c422
1 files changed, 416 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index eedd71f5506b..a8f2adfd799e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -247,7 +247,14 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
247 struct iwl_ht_agg *agg; 247 struct iwl_ht_agg *agg;
248 248
249 agg = &priv->stations[sta_id].tid[tid].agg; 249 agg = &priv->stations[sta_id].tid[tid].agg;
250 250 /*
251 * If the BT kill count is non-zero, we'll get this
252 * notification again.
253 */
254 if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
255 priv->cfg->advanced_bt_coexist) {
256 IWL_WARN(priv, "receive reply tx with bt_kill\n");
257 }
251 iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); 258 iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
252 259
253 /* check if BAR is needed */ 260 /* check if BAR is needed */
@@ -1156,6 +1163,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1156 }; 1163 };
1157 struct iwl_scan_cmd *scan; 1164 struct iwl_scan_cmd *scan;
1158 struct ieee80211_conf *conf = NULL; 1165 struct ieee80211_conf *conf = NULL;
1166 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1159 u32 rate_flags = 0; 1167 u32 rate_flags = 0;
1160 u16 cmd_len; 1168 u16 cmd_len;
1161 u16 rx_chain = 0; 1169 u16 rx_chain = 0;
@@ -1168,6 +1176,9 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1168 u8 active_chains; 1176 u8 active_chains;
1169 u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; 1177 u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
1170 1178
1179 if (vif)
1180 ctx = iwl_rxon_ctx_from_vif(vif);
1181
1171 conf = ieee80211_get_hw_conf(priv->hw); 1182 conf = ieee80211_get_hw_conf(priv->hw);
1172 1183
1173 cancel_delayed_work(&priv->scan_check); 1184 cancel_delayed_work(&priv->scan_check);
@@ -1225,7 +1236,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1225 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; 1236 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
1226 scan->quiet_time = IWL_ACTIVE_QUIET_TIME; 1237 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
1227 1238
1228 if (iwl_is_associated(priv)) { 1239 if (iwl_is_any_associated(priv)) {
1229 u16 interval = 0; 1240 u16 interval = 0;
1230 u32 extra; 1241 u32 extra;
1231 u32 suspend_time = 100; 1242 u32 suspend_time = 100;
@@ -1276,13 +1287,15 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1276 IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); 1287 IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
1277 1288
1278 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; 1289 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
1279 scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; 1290 scan->tx_cmd.sta_id = ctx->bcast_sta_id;
1280 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 1291 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
1281 1292
1282 switch (priv->scan_band) { 1293 switch (priv->scan_band) {
1283 case IEEE80211_BAND_2GHZ: 1294 case IEEE80211_BAND_2GHZ:
1284 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; 1295 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
1285 chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK) 1296 chan_mod = le32_to_cpu(
1297 priv->contexts[IWL_RXON_CTX_BSS].active.flags &
1298 RXON_FLG_CHANNEL_MODE_MSK)
1286 >> RXON_FLG_CHANNEL_MODE_POS; 1299 >> RXON_FLG_CHANNEL_MODE_POS;
1287 if (chan_mod == CHANNEL_MODE_PURE_40) { 1300 if (chan_mod == CHANNEL_MODE_PURE_40) {
1288 rate = IWL_RATE_6M_PLCP; 1301 rate = IWL_RATE_6M_PLCP;
@@ -1290,6 +1303,12 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1290 rate = IWL_RATE_1M_PLCP; 1303 rate = IWL_RATE_1M_PLCP;
1291 rate_flags = RATE_MCS_CCK_MSK; 1304 rate_flags = RATE_MCS_CCK_MSK;
1292 } 1305 }
1306 /*
1307 * Internal scans are passive, so we can indiscriminately set
1308 * the BT ignore flag on 2.4 GHz since it applies to TX only.
1309 */
1310 if (priv->cfg->advanced_bt_coexist)
1311 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
1293 scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED; 1312 scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
1294 break; 1313 break;
1295 case IEEE80211_BAND_5GHZ: 1314 case IEEE80211_BAND_5GHZ:
@@ -1327,6 +1346,12 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1327 if (priv->cfg->scan_tx_antennas[band]) 1346 if (priv->cfg->scan_tx_antennas[band])
1328 scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; 1347 scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
1329 1348
1349 if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
1350 /* operated as 1x1 in full concurrency mode */
1351 scan_tx_antennas =
1352 first_antenna(priv->cfg->scan_tx_antennas[band]);
1353 }
1354
1330 priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band], 1355 priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
1331 scan_tx_antennas); 1356 scan_tx_antennas);
1332 rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); 1357 rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
@@ -1345,6 +1370,11 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1345 1370
1346 rx_ant = first_antenna(active_chains); 1371 rx_ant = first_antenna(active_chains);
1347 } 1372 }
1373 if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
1374 /* operated as 1x1 in full concurrency mode */
1375 rx_ant = first_antenna(rx_ant);
1376 }
1377
1348 /* MIMO is not used here, but value is required */ 1378 /* MIMO is not used here, but value is required */
1349 rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; 1379 rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
1350 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; 1380 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
@@ -1394,6 +1424,11 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1394 scan->len = cpu_to_le16(cmd.len); 1424 scan->len = cpu_to_le16(cmd.len);
1395 1425
1396 set_bit(STATUS_SCAN_HW, &priv->status); 1426 set_bit(STATUS_SCAN_HW, &priv->status);
1427
1428 if (priv->cfg->ops->hcmd->set_pan_params &&
1429 priv->cfg->ops->hcmd->set_pan_params(priv))
1430 goto done;
1431
1397 if (iwl_send_cmd_sync(priv, &cmd)) 1432 if (iwl_send_cmd_sync(priv, &cmd))
1398 goto done; 1433 goto done;
1399 1434
@@ -1420,7 +1455,8 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
1420 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 1455 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1421 1456
1422 if (add) 1457 if (add)
1423 return iwl_add_bssid_station(priv, vif->bss_conf.bssid, true, 1458 return iwl_add_bssid_station(priv, vif_priv->ctx,
1459 vif->bss_conf.bssid, true,
1424 &vif_priv->ibss_bssid_sta_id); 1460 &vif_priv->ibss_bssid_sta_id);
1425 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, 1461 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
1426 vif->bss_conf.bssid); 1462 vif->bss_conf.bssid);
@@ -1453,7 +1489,7 @@ int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv)
1453 1489
1454 /* waiting for all the tx frames complete might take a while */ 1490 /* waiting for all the tx frames complete might take a while */
1455 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 1491 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
1456 if (cnt == IWL_CMD_QUEUE_NUM) 1492 if (cnt == priv->cmd_queue)
1457 continue; 1493 continue;
1458 txq = &priv->txq[cnt]; 1494 txq = &priv->txq[cnt];
1459 q = &txq->q; 1495 q = &txq->q;
@@ -1518,3 +1554,377 @@ done:
1518 ieee80211_wake_queues(priv->hw); 1554 ieee80211_wake_queues(priv->hw);
1519 mutex_unlock(&priv->mutex); 1555 mutex_unlock(&priv->mutex);
1520} 1556}
1557
1558/*
1559 * BT coex
1560 */
1561/*
1562 * Macros to access the lookup table.
1563 *
1564 * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req,
1565* wifi_prio, wifi_txrx and wifi_sh_ant_req.
1566 *
1567 * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH
1568 *
1569 * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits
1570 * one after another in 32-bit registers, and "registers" 0 through 7 contain
1571 * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order).
1572 *
1573 * These macros encode that format.
1574 */
1575#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \
1576 wifi_txrx, wifi_sh_ant_req) \
1577 (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \
1578 (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6))
1579
1580#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \
1581 lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f)))
1582#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1583 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1584 (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, \
1585 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
1586 wifi_sh_ant_req))))
1587#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1588 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1589 LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \
1590 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
1591 wifi_sh_ant_req))
1592#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \
1593 wifi_req, wifi_prio, wifi_txrx, \
1594 wifi_sh_ant_req) \
1595 LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \
1596 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
1597 wifi_sh_ant_req))
1598
1599#define LUT_WLAN_KILL_OP(lut, op, val) \
1600 lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e)))
1601#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1602 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1603 (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1604 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))))
1605#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1606 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1607 LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1608 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
1609#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1610 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1611 LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1612 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
1613
1614#define LUT_ANT_SWITCH_OP(lut, op, val) \
1615 lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1)))
1616#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1617 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1618 (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1619 wifi_req, wifi_prio, wifi_txrx, \
1620 wifi_sh_ant_req))))
1621#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1622 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1623 LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1624 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
1625#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
1626 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
1627 LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
1628 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
1629
1630static const __le32 iwlagn_def_3w_lookup[12] = {
1631 cpu_to_le32(0xaaaaaaaa),
1632 cpu_to_le32(0xaaaaaaaa),
1633 cpu_to_le32(0xaeaaaaaa),
1634 cpu_to_le32(0xaaaaaaaa),
1635 cpu_to_le32(0xcc00ff28),
1636 cpu_to_le32(0x0000aaaa),
1637 cpu_to_le32(0xcc00aaaa),
1638 cpu_to_le32(0x0000aaaa),
1639 cpu_to_le32(0xc0004000),
1640 cpu_to_le32(0x00004000),
1641 cpu_to_le32(0xf0005000),
1642 cpu_to_le32(0xf0004000),
1643};
1644
1645static const __le32 iwlagn_concurrent_lookup[12] = {
1646 cpu_to_le32(0xaaaaaaaa),
1647 cpu_to_le32(0xaaaaaaaa),
1648 cpu_to_le32(0xaaaaaaaa),
1649 cpu_to_le32(0xaaaaaaaa),
1650 cpu_to_le32(0xaaaaaaaa),
1651 cpu_to_le32(0xaaaaaaaa),
1652 cpu_to_le32(0xaaaaaaaa),
1653 cpu_to_le32(0xaaaaaaaa),
1654 cpu_to_le32(0x00000000),
1655 cpu_to_le32(0x00000000),
1656 cpu_to_le32(0x00000000),
1657 cpu_to_le32(0x00000000),
1658};
1659
1660void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
1661{
1662 struct iwlagn_bt_cmd bt_cmd = {
1663 .max_kill = IWLAGN_BT_MAX_KILL_DEFAULT,
1664 .bt3_timer_t7_value = IWLAGN_BT3_T7_DEFAULT,
1665 .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT,
1666 .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT,
1667 };
1668
1669 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
1670 sizeof(bt_cmd.bt3_lookup_table));
1671
1672 bt_cmd.prio_boost = priv->cfg->bt_prio_boost;
1673 bt_cmd.kill_ack_mask = priv->kill_ack_mask;
1674 bt_cmd.kill_cts_mask = priv->kill_cts_mask;
1675 bt_cmd.valid = priv->bt_valid;
1676
1677 /*
1678 * Configure BT coex mode to "no coexistence" when the
1679 * user disabled BT coexistence, we have no interface
1680 * (might be in monitor mode), or the interface is in
1681 * IBSS mode (no proper uCode support for coex then).
1682 */
1683 if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) {
1684 bt_cmd.flags = 0;
1685 } else {
1686 bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
1687 IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
1688 if (priv->bt_ch_announce)
1689 bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
1690 IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags);
1691 }
1692 if (priv->bt_full_concurrent)
1693 memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup,
1694 sizeof(iwlagn_concurrent_lookup));
1695 else
1696 memcpy(bt_cmd.bt3_lookup_table, iwlagn_def_3w_lookup,
1697 sizeof(iwlagn_def_3w_lookup));
1698
1699 IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n",
1700 bt_cmd.flags ? "active" : "disabled",
1701 priv->bt_full_concurrent ?
1702 "full concurrency" : "3-wire");
1703
1704 if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd))
1705 IWL_ERR(priv, "failed to send BT Coex Config\n");
1706
1707 /*
1708 * When we are doing a restart, need to also reconfigure BT
1709 * SCO to the device. If not doing a restart, bt_sco_active
1710 * will always be false, so there's no need to have an extra
1711 * variable to check for it.
1712 */
1713 if (priv->bt_sco_active) {
1714 struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
1715
1716 if (priv->bt_sco_active)
1717 sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE;
1718 if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO,
1719 sizeof(sco_cmd), &sco_cmd))
1720 IWL_ERR(priv, "failed to send BT SCO command\n");
1721 }
1722}
1723
1724static void iwlagn_bt_traffic_change_work(struct work_struct *work)
1725{
1726 struct iwl_priv *priv =
1727 container_of(work, struct iwl_priv, bt_traffic_change_work);
1728 struct iwl_rxon_context *ctx;
1729 int smps_request = -1;
1730
1731 IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
1732 priv->bt_traffic_load);
1733
1734 switch (priv->bt_traffic_load) {
1735 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1736 smps_request = IEEE80211_SMPS_AUTOMATIC;
1737 break;
1738 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1739 smps_request = IEEE80211_SMPS_DYNAMIC;
1740 break;
1741 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1742 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1743 smps_request = IEEE80211_SMPS_STATIC;
1744 break;
1745 default:
1746 IWL_ERR(priv, "Invalid BT traffic load: %d\n",
1747 priv->bt_traffic_load);
1748 break;
1749 }
1750
1751 mutex_lock(&priv->mutex);
1752
1753 if (priv->cfg->ops->lib->update_chain_flags)
1754 priv->cfg->ops->lib->update_chain_flags(priv);
1755
1756 if (smps_request != -1) {
1757 for_each_context(priv, ctx) {
1758 if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
1759 ieee80211_request_smps(ctx->vif, smps_request);
1760 }
1761 }
1762
1763 mutex_unlock(&priv->mutex);
1764}
1765
1766static void iwlagn_print_uartmsg(struct iwl_priv *priv,
1767 struct iwl_bt_uart_msg *uart_msg)
1768{
1769 IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, "
1770 "Update Req = 0x%X",
1771 (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >>
1772 BT_UART_MSG_FRAME1MSGTYPE_POS,
1773 (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >>
1774 BT_UART_MSG_FRAME1SSN_POS,
1775 (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >>
1776 BT_UART_MSG_FRAME1UPDATEREQ_POS);
1777
1778 IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, "
1779 "Chl_SeqN = 0x%X, In band = 0x%X",
1780 (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >>
1781 BT_UART_MSG_FRAME2OPENCONNECTIONS_POS,
1782 (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >>
1783 BT_UART_MSG_FRAME2TRAFFICLOAD_POS,
1784 (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >>
1785 BT_UART_MSG_FRAME2CHLSEQN_POS,
1786 (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >>
1787 BT_UART_MSG_FRAME2INBAND_POS);
1788
1789 IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, "
1790 "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X",
1791 (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >>
1792 BT_UART_MSG_FRAME3SCOESCO_POS,
1793 (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >>
1794 BT_UART_MSG_FRAME3SNIFF_POS,
1795 (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >>
1796 BT_UART_MSG_FRAME3A2DP_POS,
1797 (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >>
1798 BT_UART_MSG_FRAME3ACL_POS,
1799 (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >>
1800 BT_UART_MSG_FRAME3MASTER_POS,
1801 (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >>
1802 BT_UART_MSG_FRAME3OBEX_POS);
1803
1804 IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X",
1805 (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >>
1806 BT_UART_MSG_FRAME4IDLEDURATION_POS);
1807
1808 IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, "
1809 "eSCO Retransmissions = 0x%X",
1810 (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >>
1811 BT_UART_MSG_FRAME5TXACTIVITY_POS,
1812 (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >>
1813 BT_UART_MSG_FRAME5RXACTIVITY_POS,
1814 (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >>
1815 BT_UART_MSG_FRAME5ESCORETRANSMIT_POS);
1816
1817 IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X",
1818 (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >>
1819 BT_UART_MSG_FRAME6SNIFFINTERVAL_POS,
1820 (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >>
1821 BT_UART_MSG_FRAME6DISCOVERABLE_POS);
1822
1823 IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = "
1824 "0x%X, Connectable = 0x%X",
1825 (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >>
1826 BT_UART_MSG_FRAME7SNIFFACTIVITY_POS,
1827 (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >>
1828 BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS,
1829 (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >>
1830 BT_UART_MSG_FRAME7CONNECTABLE_POS);
1831}
1832
1833static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv,
1834 struct iwl_bt_uart_msg *uart_msg)
1835{
1836 u8 kill_ack_msk;
1837 __le32 bt_kill_ack_msg[2] = {
1838 cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) };
1839
1840 kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK |
1841 BT_UART_MSG_FRAME3SNIFF_MSK |
1842 BT_UART_MSG_FRAME3SCOESCO_MSK) &
1843 uart_msg->frame3) == 0) ? 1 : 0;
1844 if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) {
1845 priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK;
1846 priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk];
1847 /* schedule to send runtime bt_config */
1848 queue_work(priv->workqueue, &priv->bt_runtime_config);
1849 }
1850
1851}
1852
1853void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
1854 struct iwl_rx_mem_buffer *rxb)
1855{
1856 unsigned long flags;
1857 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1858 struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
1859 struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 };
1860 struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
1861 u8 last_traffic_load;
1862
1863 IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
1864 IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status);
1865 IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load);
1866 IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n",
1867 coex->bt_ci_compliance);
1868 iwlagn_print_uartmsg(priv, uart_msg);
1869
1870 last_traffic_load = priv->notif_bt_traffic_load;
1871 priv->notif_bt_traffic_load = coex->bt_traffic_load;
1872 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
1873 if (priv->bt_status != coex->bt_status ||
1874 last_traffic_load != coex->bt_traffic_load) {
1875 if (coex->bt_status) {
1876 /* BT on */
1877 if (!priv->bt_ch_announce)
1878 priv->bt_traffic_load =
1879 IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
1880 else
1881 priv->bt_traffic_load =
1882 coex->bt_traffic_load;
1883 } else {
1884 /* BT off */
1885 priv->bt_traffic_load =
1886 IWL_BT_COEX_TRAFFIC_LOAD_NONE;
1887 }
1888 priv->bt_status = coex->bt_status;
1889 queue_work(priv->workqueue,
1890 &priv->bt_traffic_change_work);
1891 }
1892 if (priv->bt_sco_active !=
1893 (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) {
1894 priv->bt_sco_active = uart_msg->frame3 &
1895 BT_UART_MSG_FRAME3SCOESCO_MSK;
1896 if (priv->bt_sco_active)
1897 sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE;
1898 iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO,
1899 sizeof(sco_cmd), &sco_cmd, NULL);
1900 }
1901 }
1902
1903 iwlagn_set_kill_ack_msk(priv, uart_msg);
1904
1905 /* FIXME: based on notification, adjust the prio_boost */
1906
1907 spin_lock_irqsave(&priv->lock, flags);
1908 priv->bt_ci_compliance = coex->bt_ci_compliance;
1909 spin_unlock_irqrestore(&priv->lock, flags);
1910}
1911
1912void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv)
1913{
1914 iwlagn_rx_handler_setup(priv);
1915 priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] =
1916 iwlagn_bt_coex_profile_notif;
1917}
1918
1919void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv)
1920{
1921 iwlagn_setup_deferred_work(priv);
1922
1923 INIT_WORK(&priv->bt_traffic_change_work,
1924 iwlagn_bt_traffic_change_work);
1925}
1926
1927void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv)
1928{
1929 cancel_work_sync(&priv->bt_traffic_change_work);
1930}