Loading drivers/net/wireless/ath/ath9k/main.c +1 −2 Original line number Diff line number Diff line Loading @@ -1532,8 +1532,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) all_wiphys_idle = ath9k_all_wiphys_idle(sc); ath9k_set_wiphy_idle(aphy, idle); if (!idle && all_wiphys_idle) enable_radio = true; enable_radio = (!idle && all_wiphys_idle); /* * After we unlock here its possible another wiphy Loading drivers/net/wireless/iwlwifi/iwl-agn-rs.c +24 −31 Original line number Diff line number Diff line Loading @@ -345,6 +345,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) !!(rate_n_flags & RATE_MCS_ANT_C_MSK); } /* * Static function to get the expected throughput from an iwl_scale_tbl_info * that wraps a NULL pointer check */ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) { if (tbl->expected_tpt) return tbl->expected_tpt[rs_index]; return 0; } /** * rs_collect_tx_data - Update the success/failure sliding window * Loading @@ -352,19 +363,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) * at this rate. window->data contains the bitmask of successful * packets. */ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, int scale_index, s32 tpt, int attempts, int successes) static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, int scale_index, int attempts, int successes) { struct iwl_rate_scale_data *window = NULL; static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); s32 fail_count; s32 fail_count, tpt; if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) return -EINVAL; /* Select window for current tx bit rate */ window = &(windows[scale_index]); window = &(tbl->win[scale_index]); /* Get expected throughput */ tpt = get_expected_tpt(tbl, scale_index); /* * Keep track of only the latest 62 tx frame attempts in this rate's Loading Loading @@ -738,16 +751,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a, return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && (a->is_SGI == b->is_SGI); } /* * Static function to get the expected throughput from an iwl_scale_tbl_info * that wraps a NULL pointer check */ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) { if (tbl->expected_tpt) return tbl->expected_tpt[rs_index]; return 0; } /* * mac80211 sends us Tx status Loading @@ -764,12 +767,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct iwl_priv *priv = (struct iwl_priv *)priv_r; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct iwl_rate_scale_data *window = NULL; enum mac80211_rate_control_flags mac_flags; u32 tx_rate; struct iwl_scale_tbl_info tbl_type; struct iwl_scale_tbl_info *curr_tbl, *other_tbl; s32 tpt = 0; struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); Loading Loading @@ -852,7 +853,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); return; } window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]); /* * Updating the frame history depends on whether packets were Loading @@ -865,8 +865,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); tpt = get_expected_tpt(curr_tbl, rs_index); rs_collect_tx_data(window, rs_index, tpt, rs_collect_tx_data(curr_tbl, rs_index, info->status.ampdu_ack_len, info->status.ampdu_ack_map); Loading Loading @@ -896,19 +895,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, * table as active/search. */ if (table_type_matches(&tbl_type, curr_tbl)) tpt = get_expected_tpt(curr_tbl, rs_index); tmp_tbl = curr_tbl; else if (table_type_matches(&tbl_type, other_tbl)) tpt = get_expected_tpt(other_tbl, rs_index); tmp_tbl = other_tbl; else continue; /* Constants mean 1 transmission, 0 successes */ if (i < retries) rs_collect_tx_data(window, rs_index, tpt, 1, 0); else rs_collect_tx_data(window, rs_index, tpt, 1, legacy_success); rs_collect_tx_data(tmp_tbl, rs_index, 1, i < retries ? 0 : legacy_success); } /* Update success/fail counts if not searching for new mode */ Loading drivers/net/wireless/iwlwifi/iwl-core.c +7 −4 Original line number Diff line number Diff line Loading @@ -307,10 +307,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); /* Allocate and init all Tx and Command queues */ ret = iwl_txq_ctx_reset(priv); /* Allocate or reset and init all Tx and Command queues */ if (!priv->txq) { ret = iwl_txq_ctx_alloc(priv); if (ret) return ret; } else iwl_txq_ctx_reset(priv); set_bit(STATUS_INIT, &priv->status); Loading drivers/net/wireless/iwlwifi/iwl-core.h +4 −1 Original line number Diff line number Diff line Loading @@ -442,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /***************************************************** * TX ******************************************************/ int iwl_txq_ctx_reset(struct iwl_priv *priv); int iwl_txq_ctx_alloc(struct iwl_priv *priv); void iwl_txq_ctx_reset(struct iwl_priv *priv); void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, Loading @@ -456,6 +457,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv, void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); Loading drivers/net/wireless/iwlwifi/iwl-tx.c +94 −13 Original line number Diff line number Diff line Loading @@ -193,10 +193,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) struct iwl_queue *q = &txq->q; struct device *dev = &priv->pci_dev->dev; int i; bool huge = false; if (q->n_bd == 0) return; for (; q->read_ptr != q->write_ptr; q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { /* we have no way to tell if it is a huge cmd ATM */ i = get_cmd_index(q, q->read_ptr, 0); if (txq->meta[i].flags & CMD_SIZE_HUGE) { huge = true; continue; } pci_unmap_single(priv->pci_dev, pci_unmap_addr(&txq->meta[i], mapping), pci_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); } if (huge) { i = q->n_window; pci_unmap_single(priv->pci_dev, pci_unmap_addr(&txq->meta[i], mapping), pci_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); } /* De-alloc array of command/tx buffers */ for (i = 0; i <= TFD_CMD_SLOTS; i++) kfree(txq->cmd[i]); Loading Loading @@ -409,6 +433,26 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, } EXPORT_SYMBOL(iwl_tx_queue_init); void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id) { int actual_slots = slots_num; if (txq_id == IWL_CMD_QUEUE_NUM) actual_slots++; memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots); txq->need_update = 0; /* Initialize queue's high/low-water marks, and head/tail indexes */ iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); /* Tell device where to find queue */ priv->cfg->ops->lib->txq_init(priv, txq); } EXPORT_SYMBOL(iwl_tx_queue_reset); /** * iwl_hw_txq_ctx_free - Free TXQ Context * Loading @@ -420,8 +464,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) /* Tx queues */ if (priv->txq) { for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) if (txq_id == IWL_CMD_QUEUE_NUM) iwl_cmd_queue_free(priv); else Loading @@ -437,15 +480,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) EXPORT_SYMBOL(iwl_hw_txq_ctx_free); /** * iwl_txq_ctx_reset - Reset TX queue context * Destroys all DMA structures and initialize them again * iwl_txq_ctx_alloc - allocate TX queue context * Allocate all Tx DMA structures and initialize them * * @param priv * @return error code */ int iwl_txq_ctx_reset(struct iwl_priv *priv) int iwl_txq_ctx_alloc(struct iwl_priv *priv) { int ret = 0; int ret; int txq_id, slots_num; unsigned long flags; Loading Loading @@ -503,8 +546,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) return ret; } void iwl_txq_ctx_reset(struct iwl_priv *priv) { int txq_id, slots_num; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); /* Turn off all Tx DMA fifos */ priv->cfg->ops->lib->txq_set_sched(priv, 0); /* Tell NIC where to find the "keep warm" buffer */ iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); spin_unlock_irqrestore(&priv->lock, flags); /* Alloc and init all Tx queues, including the command queue (#4) */ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { slots_num = txq_id == IWL_CMD_QUEUE_NUM ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id); } } /** * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory * iwl_txq_ctx_stop - Stop all Tx DMA channels */ void iwl_txq_ctx_stop(struct iwl_priv *priv) { Loading @@ -524,9 +590,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv) 1000); } spin_unlock_irqrestore(&priv->lock, flags); /* Deallocate memory for all Tx queues */ iwl_hw_txq_ctx_free(priv); } EXPORT_SYMBOL(iwl_txq_ctx_stop); Loading Loading @@ -1049,6 +1112,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) spin_lock_irqsave(&priv->hcmd_lock, flags); /* If this is a huge cmd, mark the huge flag also on the meta.flags * of the _original_ cmd. This is used for DMA mapping clean up. */ if (cmd->flags & CMD_SIZE_HUGE) { idx = get_cmd_index(q, q->write_ptr, 0); txq->meta[idx].flags = CMD_SIZE_HUGE; } idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); out_cmd = txq->cmd[idx]; out_meta = &txq->meta[idx]; Loading Loading @@ -1226,6 +1297,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced Loading @@ -1239,9 +1311,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) return; } cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index]; /* If this is a huge cmd, clear the huge flag on the meta.flags * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap * the DMA buffer for the scan (huge) command. */ if (huge) { cmd_index = get_cmd_index(&txq->q, index, 0); txq->meta[cmd_index].flags = 0; } cmd_index = get_cmd_index(&txq->q, index, huge); cmd = txq->cmd[cmd_index]; meta = &txq->meta[cmd_index]; pci_unmap_single(priv->pci_dev, pci_unmap_addr(meta, mapping), Loading @@ -1263,6 +1343,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) get_cmd_string(cmd->hdr.cmd)); wake_up_interruptible(&priv->wait_command_queue); } meta->flags = 0; } EXPORT_SYMBOL(iwl_tx_cmd_complete); Loading Loading
drivers/net/wireless/ath/ath9k/main.c +1 −2 Original line number Diff line number Diff line Loading @@ -1532,8 +1532,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) all_wiphys_idle = ath9k_all_wiphys_idle(sc); ath9k_set_wiphy_idle(aphy, idle); if (!idle && all_wiphys_idle) enable_radio = true; enable_radio = (!idle && all_wiphys_idle); /* * After we unlock here its possible another wiphy Loading
drivers/net/wireless/iwlwifi/iwl-agn-rs.c +24 −31 Original line number Diff line number Diff line Loading @@ -345,6 +345,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) !!(rate_n_flags & RATE_MCS_ANT_C_MSK); } /* * Static function to get the expected throughput from an iwl_scale_tbl_info * that wraps a NULL pointer check */ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) { if (tbl->expected_tpt) return tbl->expected_tpt[rs_index]; return 0; } /** * rs_collect_tx_data - Update the success/failure sliding window * Loading @@ -352,19 +363,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) * at this rate. window->data contains the bitmask of successful * packets. */ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, int scale_index, s32 tpt, int attempts, int successes) static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, int scale_index, int attempts, int successes) { struct iwl_rate_scale_data *window = NULL; static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); s32 fail_count; s32 fail_count, tpt; if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) return -EINVAL; /* Select window for current tx bit rate */ window = &(windows[scale_index]); window = &(tbl->win[scale_index]); /* Get expected throughput */ tpt = get_expected_tpt(tbl, scale_index); /* * Keep track of only the latest 62 tx frame attempts in this rate's Loading Loading @@ -738,16 +751,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a, return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && (a->is_SGI == b->is_SGI); } /* * Static function to get the expected throughput from an iwl_scale_tbl_info * that wraps a NULL pointer check */ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) { if (tbl->expected_tpt) return tbl->expected_tpt[rs_index]; return 0; } /* * mac80211 sends us Tx status Loading @@ -764,12 +767,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct iwl_priv *priv = (struct iwl_priv *)priv_r; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct iwl_rate_scale_data *window = NULL; enum mac80211_rate_control_flags mac_flags; u32 tx_rate; struct iwl_scale_tbl_info tbl_type; struct iwl_scale_tbl_info *curr_tbl, *other_tbl; s32 tpt = 0; struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); Loading Loading @@ -852,7 +853,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); return; } window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]); /* * Updating the frame history depends on whether packets were Loading @@ -865,8 +865,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); tpt = get_expected_tpt(curr_tbl, rs_index); rs_collect_tx_data(window, rs_index, tpt, rs_collect_tx_data(curr_tbl, rs_index, info->status.ampdu_ack_len, info->status.ampdu_ack_map); Loading Loading @@ -896,19 +895,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, * table as active/search. */ if (table_type_matches(&tbl_type, curr_tbl)) tpt = get_expected_tpt(curr_tbl, rs_index); tmp_tbl = curr_tbl; else if (table_type_matches(&tbl_type, other_tbl)) tpt = get_expected_tpt(other_tbl, rs_index); tmp_tbl = other_tbl; else continue; /* Constants mean 1 transmission, 0 successes */ if (i < retries) rs_collect_tx_data(window, rs_index, tpt, 1, 0); else rs_collect_tx_data(window, rs_index, tpt, 1, legacy_success); rs_collect_tx_data(tmp_tbl, rs_index, 1, i < retries ? 0 : legacy_success); } /* Update success/fail counts if not searching for new mode */ Loading
drivers/net/wireless/iwlwifi/iwl-core.c +7 −4 Original line number Diff line number Diff line Loading @@ -307,10 +307,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); /* Allocate and init all Tx and Command queues */ ret = iwl_txq_ctx_reset(priv); /* Allocate or reset and init all Tx and Command queues */ if (!priv->txq) { ret = iwl_txq_ctx_alloc(priv); if (ret) return ret; } else iwl_txq_ctx_reset(priv); set_bit(STATUS_INIT, &priv->status); Loading
drivers/net/wireless/iwlwifi/iwl-core.h +4 −1 Original line number Diff line number Diff line Loading @@ -442,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /***************************************************** * TX ******************************************************/ int iwl_txq_ctx_reset(struct iwl_priv *priv); int iwl_txq_ctx_alloc(struct iwl_priv *priv); void iwl_txq_ctx_reset(struct iwl_priv *priv); void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq, Loading @@ -456,6 +457,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv, void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); Loading
drivers/net/wireless/iwlwifi/iwl-tx.c +94 −13 Original line number Diff line number Diff line Loading @@ -193,10 +193,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) struct iwl_queue *q = &txq->q; struct device *dev = &priv->pci_dev->dev; int i; bool huge = false; if (q->n_bd == 0) return; for (; q->read_ptr != q->write_ptr; q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { /* we have no way to tell if it is a huge cmd ATM */ i = get_cmd_index(q, q->read_ptr, 0); if (txq->meta[i].flags & CMD_SIZE_HUGE) { huge = true; continue; } pci_unmap_single(priv->pci_dev, pci_unmap_addr(&txq->meta[i], mapping), pci_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); } if (huge) { i = q->n_window; pci_unmap_single(priv->pci_dev, pci_unmap_addr(&txq->meta[i], mapping), pci_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); } /* De-alloc array of command/tx buffers */ for (i = 0; i <= TFD_CMD_SLOTS; i++) kfree(txq->cmd[i]); Loading Loading @@ -409,6 +433,26 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, } EXPORT_SYMBOL(iwl_tx_queue_init); void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id) { int actual_slots = slots_num; if (txq_id == IWL_CMD_QUEUE_NUM) actual_slots++; memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots); txq->need_update = 0; /* Initialize queue's high/low-water marks, and head/tail indexes */ iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); /* Tell device where to find queue */ priv->cfg->ops->lib->txq_init(priv, txq); } EXPORT_SYMBOL(iwl_tx_queue_reset); /** * iwl_hw_txq_ctx_free - Free TXQ Context * Loading @@ -420,8 +464,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) /* Tx queues */ if (priv->txq) { for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) if (txq_id == IWL_CMD_QUEUE_NUM) iwl_cmd_queue_free(priv); else Loading @@ -437,15 +480,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) EXPORT_SYMBOL(iwl_hw_txq_ctx_free); /** * iwl_txq_ctx_reset - Reset TX queue context * Destroys all DMA structures and initialize them again * iwl_txq_ctx_alloc - allocate TX queue context * Allocate all Tx DMA structures and initialize them * * @param priv * @return error code */ int iwl_txq_ctx_reset(struct iwl_priv *priv) int iwl_txq_ctx_alloc(struct iwl_priv *priv) { int ret = 0; int ret; int txq_id, slots_num; unsigned long flags; Loading Loading @@ -503,8 +546,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) return ret; } void iwl_txq_ctx_reset(struct iwl_priv *priv) { int txq_id, slots_num; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); /* Turn off all Tx DMA fifos */ priv->cfg->ops->lib->txq_set_sched(priv, 0); /* Tell NIC where to find the "keep warm" buffer */ iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); spin_unlock_irqrestore(&priv->lock, flags); /* Alloc and init all Tx queues, including the command queue (#4) */ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { slots_num = txq_id == IWL_CMD_QUEUE_NUM ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id); } } /** * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory * iwl_txq_ctx_stop - Stop all Tx DMA channels */ void iwl_txq_ctx_stop(struct iwl_priv *priv) { Loading @@ -524,9 +590,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv) 1000); } spin_unlock_irqrestore(&priv->lock, flags); /* Deallocate memory for all Tx queues */ iwl_hw_txq_ctx_free(priv); } EXPORT_SYMBOL(iwl_txq_ctx_stop); Loading Loading @@ -1049,6 +1112,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) spin_lock_irqsave(&priv->hcmd_lock, flags); /* If this is a huge cmd, mark the huge flag also on the meta.flags * of the _original_ cmd. This is used for DMA mapping clean up. */ if (cmd->flags & CMD_SIZE_HUGE) { idx = get_cmd_index(q, q->write_ptr, 0); txq->meta[idx].flags = CMD_SIZE_HUGE; } idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); out_cmd = txq->cmd[idx]; out_meta = &txq->meta[idx]; Loading Loading @@ -1226,6 +1297,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced Loading @@ -1239,9 +1311,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) return; } cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index]; /* If this is a huge cmd, clear the huge flag on the meta.flags * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap * the DMA buffer for the scan (huge) command. */ if (huge) { cmd_index = get_cmd_index(&txq->q, index, 0); txq->meta[cmd_index].flags = 0; } cmd_index = get_cmd_index(&txq->q, index, huge); cmd = txq->cmd[cmd_index]; meta = &txq->meta[cmd_index]; pci_unmap_single(priv->pci_dev, pci_unmap_addr(meta, mapping), Loading @@ -1263,6 +1343,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) get_cmd_string(cmd->hdr.cmd)); wake_up_interruptible(&priv->wait_command_queue); } meta->flags = 0; } EXPORT_SYMBOL(iwl_tx_cmd_complete); Loading