aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c65
1 files changed, 36 insertions, 29 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 78b1a7a4ca40..907a53ebc6e4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -63,7 +63,7 @@ static const u16 default_tid_to_tx_fifo[] = {
63 * Does NOT advance any TFD circular buffer read/write indexes 63 * Does NOT advance any TFD circular buffer read/write indexes
64 * Does NOT free the TFD itself (which is within circular buffer) 64 * Does NOT free the TFD itself (which is within circular buffer)
65 */ 65 */
66int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) 66static int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
67{ 67{
68 struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0]; 68 struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0];
69 struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; 69 struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
@@ -115,10 +115,8 @@ int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
115 } 115 }
116 return 0; 116 return 0;
117} 117}
118EXPORT_SYMBOL(iwl_hw_txq_free_tfd);
119 118
120 119static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
121int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
122 dma_addr_t addr, u16 len) 120 dma_addr_t addr, u16 len)
123{ 121{
124 int index, is_odd; 122 int index, is_odd;
@@ -126,7 +124,7 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
126 u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs); 124 u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs);
127 125
128 /* Each TFD can point to a maximum 20 Tx buffers */ 126 /* Each TFD can point to a maximum 20 Tx buffers */
129 if ((num_tbs >= MAX_NUM_OF_TBS) || (num_tbs < 0)) { 127 if (num_tbs >= MAX_NUM_OF_TBS) {
130 IWL_ERROR("Error can not send more than %d chunks\n", 128 IWL_ERROR("Error can not send more than %d chunks\n",
131 MAX_NUM_OF_TBS); 129 MAX_NUM_OF_TBS);
132 return -EINVAL; 130 return -EINVAL;
@@ -151,7 +149,6 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
151 149
152 return 0; 150 return 0;
153} 151}
154EXPORT_SYMBOL(iwl_hw_txq_attach_buf_to_tfd);
155 152
156/** 153/**
157 * iwl_txq_update_write_ptr - Send new write index to hardware 154 * iwl_txq_update_write_ptr - Send new write index to hardware
@@ -478,7 +475,6 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
478} 475}
479EXPORT_SYMBOL(iwl_hw_txq_ctx_free); 476EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
480 477
481
482/** 478/**
483 * iwl_txq_ctx_reset - Reset TX queue context 479 * iwl_txq_ctx_reset - Reset TX queue context
484 * Destroys all DMA structures and initialise them again 480 * Destroys all DMA structures and initialise them again
@@ -545,6 +541,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
545 error_kw: 541 error_kw:
546 return ret; 542 return ret;
547} 543}
544
548/** 545/**
549 * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory 546 * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
550 */ 547 */
@@ -796,11 +793,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
796 goto drop_unlock; 793 goto drop_unlock;
797 } 794 }
798 795
799 if (!priv->vif) {
800 IWL_DEBUG_DROP("Dropping - !priv->vif\n");
801 goto drop_unlock;
802 }
803
804 if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == 796 if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
805 IWL_INVALID_RATE) { 797 IWL_INVALID_RATE) {
806 IWL_ERROR("ERROR: No TX rate available.\n"); 798 IWL_ERROR("ERROR: No TX rate available.\n");
@@ -822,16 +814,18 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
822 814
823 /* drop all data frame if we are not associated */ 815 /* drop all data frame if we are not associated */
824 if (ieee80211_is_data(fc) && 816 if (ieee80211_is_data(fc) &&
825 (!iwl_is_associated(priv) || 817 (priv->iw_mode != NL80211_IFTYPE_MONITOR ||
826 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) || 818 !(info->flags & IEEE80211_TX_CTL_INJECTED)) && /* packet injection */
827 !priv->assoc_station_added)) { 819 (!iwl_is_associated(priv) ||
820 ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
821 !priv->assoc_station_added)) {
828 IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n"); 822 IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
829 goto drop_unlock; 823 goto drop_unlock;
830 } 824 }
831 825
832 spin_unlock_irqrestore(&priv->lock, flags); 826 spin_unlock_irqrestore(&priv->lock, flags);
833 827
834 hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc)); 828 hdr_len = ieee80211_hdrlen(fc);
835 829
836 /* Find (or create) index into station table for destination station */ 830 /* Find (or create) index into station table for destination station */
837 sta_id = iwl_get_sta_id(priv, hdr); 831 sta_id = iwl_get_sta_id(priv, hdr);
@@ -849,7 +843,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
849 txq_id = swq_id; 843 txq_id = swq_id;
850 if (ieee80211_is_data_qos(fc)) { 844 if (ieee80211_is_data_qos(fc)) {
851 qc = ieee80211_get_qos_ctl(hdr); 845 qc = ieee80211_get_qos_ctl(hdr);
852 tid = qc[0] & 0xf; 846 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
853 seq_number = priv->stations[sta_id].tid[tid].seq_number; 847 seq_number = priv->stations[sta_id].tid[tid].seq_number;
854 seq_number &= IEEE80211_SCTL_SEQ; 848 seq_number &= IEEE80211_SCTL_SEQ;
855 hdr->seq_ctrl = hdr->seq_ctrl & 849 hdr->seq_ctrl = hdr->seq_ctrl &
@@ -1064,7 +1058,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1064 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | 1058 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
1065 INDEX_TO_SEQ(q->write_ptr)); 1059 INDEX_TO_SEQ(q->write_ptr));
1066 if (out_cmd->meta.flags & CMD_SIZE_HUGE) 1060 if (out_cmd->meta.flags & CMD_SIZE_HUGE)
1067 out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME); 1061 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
1068 len = (idx == TFD_CMD_SLOTS) ? 1062 len = (idx == TFD_CMD_SLOTS) ?
1069 IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd); 1063 IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
1070 phys_addr = pci_map_single(priv->pci_dev, out_cmd, len, 1064 phys_addr = pci_map_single(priv->pci_dev, out_cmd, len,
@@ -1072,12 +1066,26 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1072 phys_addr += offsetof(struct iwl_cmd, hdr); 1066 phys_addr += offsetof(struct iwl_cmd, hdr);
1073 iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); 1067 iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
1074 1068
1075 IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, " 1069#ifdef CONFIG_IWLWIFI_DEBUG
1076 "%d bytes at %d[%d]:%d\n", 1070 switch (out_cmd->hdr.cmd) {
1077 get_cmd_string(out_cmd->hdr.cmd), 1071 case REPLY_TX_LINK_QUALITY_CMD:
1078 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), 1072 case SENSITIVITY_CMD:
1079 fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); 1073 IWL_DEBUG_HC_DUMP("Sending command %s (#%x), seq: 0x%04X, "
1080 1074 "%d bytes at %d[%d]:%d\n",
1075 get_cmd_string(out_cmd->hdr.cmd),
1076 out_cmd->hdr.cmd,
1077 le16_to_cpu(out_cmd->hdr.sequence), fix_size,
1078 q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
1079 break;
1080 default:
1081 IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
1082 "%d bytes at %d[%d]:%d\n",
1083 get_cmd_string(out_cmd->hdr.cmd),
1084 out_cmd->hdr.cmd,
1085 le16_to_cpu(out_cmd->hdr.sequence), fix_size,
1086 q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
1087 }
1088#endif
1081 txq->need_update = 1; 1089 txq->need_update = 1;
1082 1090
1083 /* Set up entry in queue's byte count circular buffer */ 1091 /* Set up entry in queue's byte count circular buffer */
@@ -1185,17 +1193,16 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1185 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 1193 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
1186 int txq_id = SEQ_TO_QUEUE(sequence); 1194 int txq_id = SEQ_TO_QUEUE(sequence);
1187 int index = SEQ_TO_INDEX(sequence); 1195 int index = SEQ_TO_INDEX(sequence);
1188 int huge = sequence & SEQ_HUGE_FRAME;
1189 int cmd_index; 1196 int cmd_index;
1197 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
1190 struct iwl_cmd *cmd; 1198 struct iwl_cmd *cmd;
1191 1199
1192 /* If a Tx command is being handled and it isn't in the actual 1200 /* If a Tx command is being handled and it isn't in the actual
1193 * command queue then there a command routing bug has been introduced 1201 * command queue then there a command routing bug has been introduced
1194 * in the queue management code. */ 1202 * in the queue management code. */
1195 if (txq_id != IWL_CMD_QUEUE_NUM) 1203 if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
1196 IWL_ERROR("Error wrong command queue %d command id 0x%X\n", 1204 "wrong command queue %d, command id 0x%X\n", txq_id, pkt->hdr.cmd))
1197 txq_id, pkt->hdr.cmd); 1205 return;
1198 BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
1199 1206
1200 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); 1207 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
1201 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; 1208 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];