aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-ucode.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c95
1 files changed, 90 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 6f77441cb65a..a7961bf395fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -52,6 +52,19 @@ static const s8 iwlagn_default_queue_to_tx_fifo[] = {
52 IWL_TX_FIFO_UNUSED, 52 IWL_TX_FIFO_UNUSED,
53}; 53};
54 54
55static const s8 iwlagn_ipan_queue_to_tx_fifo[] = {
56 IWL_TX_FIFO_VO,
57 IWL_TX_FIFO_VI,
58 IWL_TX_FIFO_BE,
59 IWL_TX_FIFO_BK,
60 IWL_TX_FIFO_BK_IPAN,
61 IWL_TX_FIFO_BE_IPAN,
62 IWL_TX_FIFO_VI_IPAN,
63 IWL_TX_FIFO_VO_IPAN,
64 IWL_TX_FIFO_BE_IPAN,
65 IWLAGN_CMD_FIFO_NUM,
66};
67
55static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { 68static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
56 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, 69 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
57 0, COEX_UNASSOC_IDLE_FLAGS}, 70 0, COEX_UNASSOC_IDLE_FLAGS},
@@ -329,8 +342,54 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
329 sizeof(coex_cmd), &coex_cmd); 342 sizeof(coex_cmd), &coex_cmd);
330} 343}
331 344
345static const u8 iwlagn_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
346 ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
347 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
348 ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
349 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
350 ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
351 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
352 ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
353 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
354 ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
355 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
356 ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
357 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
358 ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
359 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
360 ((BT_COEX_PRIO_TBL_PRIO_COEX_OFF << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
361 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
362 ((BT_COEX_PRIO_TBL_PRIO_COEX_ON << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
363 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
364 0, 0, 0, 0, 0, 0, 0
365};
366
367static void iwlagn_send_prio_tbl(struct iwl_priv *priv)
368{
369 struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd;
370
371 memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl,
372 sizeof(iwlagn_bt_prio_tbl));
373 if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE,
374 sizeof(prio_tbl_cmd), &prio_tbl_cmd))
375 IWL_ERR(priv, "failed to send BT prio tbl command\n");
376}
377
378static void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
379{
380 struct iwl_bt_coex_prot_env_cmd env_cmd;
381
382 env_cmd.action = action;
383 env_cmd.type = type;
384 if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
385 sizeof(env_cmd), &env_cmd))
386 IWL_ERR(priv, "failed to send BT env command\n");
387}
388
389
332int iwlagn_alive_notify(struct iwl_priv *priv) 390int iwlagn_alive_notify(struct iwl_priv *priv)
333{ 391{
392 const s8 *queues;
334 u32 a; 393 u32 a;
335 unsigned long flags; 394 unsigned long flags;
336 int i, chan; 395 int i, chan;
@@ -365,7 +424,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
365 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); 424 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
366 425
367 iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL, 426 iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL,
368 IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num)); 427 IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv));
369 iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0); 428 iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0);
370 429
371 /* initiate the queues */ 430 /* initiate the queues */
@@ -391,7 +450,13 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
391 /* Activate all Tx DMA/FIFO channels */ 450 /* Activate all Tx DMA/FIFO channels */
392 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7)); 451 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
393 452
394 iwlagn_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); 453 /* map queues to FIFOs */
454 if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
455 queues = iwlagn_ipan_queue_to_tx_fifo;
456 else
457 queues = iwlagn_default_queue_to_tx_fifo;
458
459 iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0);
395 460
396 /* make sure all queue are not stopped */ 461 /* make sure all queue are not stopped */
397 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); 462 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
@@ -400,11 +465,12 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
400 465
401 /* reset to 0 to enable all the queue first */ 466 /* reset to 0 to enable all the queue first */
402 priv->txq_ctx_active_msk = 0; 467 priv->txq_ctx_active_msk = 0;
403 /* map qos queues to fifos one-to-one */ 468
404 BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10); 469 BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10);
470 BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10);
405 471
406 for (i = 0; i < ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); i++) { 472 for (i = 0; i < 10; i++) {
407 int ac = iwlagn_default_queue_to_tx_fifo[i]; 473 int ac = queues[i];
408 474
409 iwl_txq_ctx_activate(priv, i); 475 iwl_txq_ctx_activate(priv, i);
410 476
@@ -416,6 +482,25 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
416 482
417 spin_unlock_irqrestore(&priv->lock, flags); 483 spin_unlock_irqrestore(&priv->lock, flags);
418 484
485 if (priv->cfg->advanced_bt_coexist) {
486 /* Configure Bluetooth device coexistence support */
487 /* need to perform this before any calibration */
488 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
489 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
490 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
491 priv->cfg->ops->hcmd->send_bt_config(priv);
492 priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
493
494 if (bt_coex_active && priv->iw_mode != NL80211_IFTYPE_ADHOC) {
495 iwlagn_send_prio_tbl(priv);
496 iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
497 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
498 iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
499 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
500 }
501
502 }
503
419 iwlagn_send_wimax_coex(priv); 504 iwlagn_send_wimax_coex(priv);
420 505
421 iwlagn_set_Xtal_calib(priv); 506 iwlagn_set_Xtal_calib(priv);