diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 65 |
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 | */ |
66 | int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | 66 | static 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 | } |
118 | EXPORT_SYMBOL(iwl_hw_txq_free_tfd); | ||
119 | 118 | ||
120 | 119 | static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, | |
121 | int 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 | } |
154 | EXPORT_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 | } |
479 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); | 476 | EXPORT_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]; |