diff options
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 23 |
2 files changed, 22 insertions, 39 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index e129661e4d99..1d116c06cd1c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c | |||
@@ -202,7 +202,6 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
202 | struct iwl_tx_cmd *tx_cmd, | 202 | struct iwl_tx_cmd *tx_cmd, |
203 | struct ieee80211_tx_info *info, u8 sta_id) | 203 | struct ieee80211_tx_info *info, u8 sta_id) |
204 | { | 204 | { |
205 | struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); | ||
206 | struct ieee80211_hdr *hdr = (void *)skb->data; | 205 | struct ieee80211_hdr *hdr = (void *)skb->data; |
207 | __le16 fc = hdr->frame_control; | 206 | __le16 fc = hdr->frame_control; |
208 | u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags); | 207 | u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags); |
@@ -284,9 +283,8 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
284 | tx_flags |= TX_CMD_FLG_WRITE_TX_POWER; | 283 | tx_flags |= TX_CMD_FLG_WRITE_TX_POWER; |
285 | 284 | ||
286 | tx_cmd->tx_flags = cpu_to_le32(tx_flags); | 285 | tx_cmd->tx_flags = cpu_to_le32(tx_flags); |
287 | /* Total # bytes to be transmitted */ | 286 | /* Total # bytes to be transmitted - PCIe code will adjust for A-MSDU */ |
288 | tx_cmd->len = cpu_to_le16((u16)skb->len + | 287 | tx_cmd->len = cpu_to_le16((u16)skb->len); |
289 | (uintptr_t)skb_info->driver_data[0]); | ||
290 | tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); | 288 | tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); |
291 | tx_cmd->sta_id = sta_id; | 289 | tx_cmd->sta_id = sta_id; |
292 | 290 | ||
@@ -555,9 +553,6 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | |||
555 | info.hw_queue != info.control.vif->cab_queue))) | 553 | info.hw_queue != info.control.vif->cab_queue))) |
556 | return -1; | 554 | return -1; |
557 | 555 | ||
558 | /* This holds the amsdu headers length */ | ||
559 | skb_info->driver_data[0] = (void *)(uintptr_t)0; | ||
560 | |||
561 | queue = info.hw_queue; | 556 | queue = info.hw_queue; |
562 | 557 | ||
563 | /* | 558 | /* |
@@ -644,7 +639,7 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
644 | unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len; | 639 | unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len; |
645 | bool ipv4 = (skb->protocol == htons(ETH_P_IP)); | 640 | bool ipv4 = (skb->protocol == htons(ETH_P_IP)); |
646 | u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0; | 641 | u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0; |
647 | u16 amsdu_add, snap_ip_tcp, pad, i = 0; | 642 | u16 snap_ip_tcp, pad, i = 0; |
648 | unsigned int dbg_max_amsdu_len; | 643 | unsigned int dbg_max_amsdu_len; |
649 | netdev_features_t netdev_features = NETIF_F_CSUM_MASK | NETIF_F_SG; | 644 | netdev_features_t netdev_features = NETIF_F_CSUM_MASK | NETIF_F_SG; |
650 | u8 *qc, tid, txf; | 645 | u8 *qc, tid, txf; |
@@ -746,21 +741,6 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
746 | 741 | ||
747 | /* This skb fits in one single A-MSDU */ | 742 | /* This skb fits in one single A-MSDU */ |
748 | if (num_subframes * mss >= tcp_payload_len) { | 743 | if (num_subframes * mss >= tcp_payload_len) { |
749 | struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); | ||
750 | |||
751 | /* | ||
752 | * Compute the length of all the data added for the A-MSDU. | ||
753 | * This will be used to compute the length to write in the TX | ||
754 | * command. We have: SNAP + IP + TCP for n -1 subframes and | ||
755 | * ETH header for n subframes. Note that the original skb | ||
756 | * already had one set of SNAP / IP / TCP headers. | ||
757 | */ | ||
758 | num_subframes = DIV_ROUND_UP(tcp_payload_len, mss); | ||
759 | amsdu_add = num_subframes * sizeof(struct ethhdr) + | ||
760 | (num_subframes - 1) * (snap_ip_tcp + pad); | ||
761 | /* This holds the amsdu headers length */ | ||
762 | skb_info->driver_data[0] = (void *)(uintptr_t)amsdu_add; | ||
763 | |||
764 | __skb_queue_tail(mpdus_skb, skb); | 744 | __skb_queue_tail(mpdus_skb, skb); |
765 | return 0; | 745 | return 0; |
766 | } | 746 | } |
@@ -799,14 +779,6 @@ segment: | |||
799 | ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes); | 779 | ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes); |
800 | 780 | ||
801 | if (tcp_payload_len > mss) { | 781 | if (tcp_payload_len > mss) { |
802 | struct ieee80211_tx_info *skb_info = | ||
803 | IEEE80211_SKB_CB(tmp); | ||
804 | |||
805 | num_subframes = DIV_ROUND_UP(tcp_payload_len, mss); | ||
806 | amsdu_add = num_subframes * sizeof(struct ethhdr) + | ||
807 | (num_subframes - 1) * (snap_ip_tcp + pad); | ||
808 | skb_info->driver_data[0] = | ||
809 | (void *)(uintptr_t)amsdu_add; | ||
810 | skb_shinfo(tmp)->gso_size = mss; | 782 | skb_shinfo(tmp)->gso_size = mss; |
811 | } else { | 783 | } else { |
812 | qc = ieee80211_get_qos_ctl((void *)tmp->data); | 784 | qc = ieee80211_get_qos_ctl((void *)tmp->data); |
@@ -1052,7 +1024,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
1052 | struct ieee80211_sta *sta) | 1024 | struct ieee80211_sta *sta) |
1053 | { | 1025 | { |
1054 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); | 1026 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); |
1055 | struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); | ||
1056 | struct ieee80211_tx_info info; | 1027 | struct ieee80211_tx_info info; |
1057 | struct sk_buff_head mpdus_skbs; | 1028 | struct sk_buff_head mpdus_skbs; |
1058 | unsigned int payload_len; | 1029 | unsigned int payload_len; |
@@ -1066,9 +1037,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
1066 | 1037 | ||
1067 | memcpy(&info, skb->cb, sizeof(info)); | 1038 | memcpy(&info, skb->cb, sizeof(info)); |
1068 | 1039 | ||
1069 | /* This holds the amsdu headers length */ | ||
1070 | skb_info->driver_data[0] = (void *)(uintptr_t)0; | ||
1071 | |||
1072 | if (!skb_is_gso(skb)) | 1040 | if (!skb_is_gso(skb)) |
1073 | return iwl_mvm_tx_mpdu(mvm, skb, &info, sta); | 1041 | return iwl_mvm_tx_mpdu(mvm, skb, &info, sta); |
1074 | 1042 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 5f840f16f40b..e1bfc9522cbe 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c | |||
@@ -2096,6 +2096,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, | |||
2096 | struct iwl_cmd_meta *out_meta, | 2096 | struct iwl_cmd_meta *out_meta, |
2097 | struct iwl_device_cmd *dev_cmd, u16 tb1_len) | 2097 | struct iwl_device_cmd *dev_cmd, u16 tb1_len) |
2098 | { | 2098 | { |
2099 | struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; | ||
2099 | struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; | 2100 | struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; |
2100 | struct ieee80211_hdr *hdr = (void *)skb->data; | 2101 | struct ieee80211_hdr *hdr = (void *)skb->data; |
2101 | unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room; | 2102 | unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room; |
@@ -2145,6 +2146,13 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, | |||
2145 | */ | 2146 | */ |
2146 | skb_pull(skb, hdr_len + iv_len); | 2147 | skb_pull(skb, hdr_len + iv_len); |
2147 | 2148 | ||
2149 | /* | ||
2150 | * Remove the length of all the headers that we don't actually | ||
2151 | * have in the MPDU by themselves, but that we duplicate into | ||
2152 | * all the different MSDUs inside the A-MSDU. | ||
2153 | */ | ||
2154 | le16_add_cpu(&tx_cmd->len, -snap_ip_tcp_hdrlen); | ||
2155 | |||
2148 | tso_start(skb, &tso); | 2156 | tso_start(skb, &tso); |
2149 | 2157 | ||
2150 | while (total_len) { | 2158 | while (total_len) { |
@@ -2155,7 +2163,7 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, | |||
2155 | unsigned int hdr_tb_len; | 2163 | unsigned int hdr_tb_len; |
2156 | dma_addr_t hdr_tb_phys; | 2164 | dma_addr_t hdr_tb_phys; |
2157 | struct tcphdr *tcph; | 2165 | struct tcphdr *tcph; |
2158 | u8 *iph; | 2166 | u8 *iph, *subf_hdrs_start = hdr_page->pos; |
2159 | 2167 | ||
2160 | total_len -= data_left; | 2168 | total_len -= data_left; |
2161 | 2169 | ||
@@ -2216,6 +2224,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, | |||
2216 | hdr_tb_len, false); | 2224 | hdr_tb_len, false); |
2217 | trace_iwlwifi_dev_tx_tso_chunk(trans->dev, start_hdr, | 2225 | trace_iwlwifi_dev_tx_tso_chunk(trans->dev, start_hdr, |
2218 | hdr_tb_len); | 2226 | hdr_tb_len); |
2227 | /* add this subframe's headers' length to the tx_cmd */ | ||
2228 | le16_add_cpu(&tx_cmd->len, hdr_page->pos - subf_hdrs_start); | ||
2219 | 2229 | ||
2220 | /* prepare the start_hdr for the next subframe */ | 2230 | /* prepare the start_hdr for the next subframe */ |
2221 | start_hdr = hdr_page->pos; | 2231 | start_hdr = hdr_page->pos; |
@@ -2408,9 +2418,10 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
2408 | tb1_len = len; | 2418 | tb1_len = len; |
2409 | } | 2419 | } |
2410 | 2420 | ||
2411 | /* The first TB points to bi-directional DMA data */ | 2421 | /* |
2412 | memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr, | 2422 | * The first TB points to bi-directional DMA data, we'll |
2413 | IWL_FIRST_TB_SIZE); | 2423 | * memcpy the data into it later. |
2424 | */ | ||
2414 | iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, | 2425 | iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, |
2415 | IWL_FIRST_TB_SIZE, true); | 2426 | IWL_FIRST_TB_SIZE, true); |
2416 | 2427 | ||
@@ -2434,6 +2445,10 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
2434 | goto out_err; | 2445 | goto out_err; |
2435 | } | 2446 | } |
2436 | 2447 | ||
2448 | /* building the A-MSDU might have changed this data, so memcpy it now */ | ||
2449 | memcpy(&txq->first_tb_bufs[txq->write_ptr], &dev_cmd->hdr, | ||
2450 | IWL_FIRST_TB_SIZE); | ||
2451 | |||
2437 | tfd = iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr); | 2452 | tfd = iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr); |
2438 | /* Set up entry for this TFD in Tx byte-count array */ | 2453 | /* Set up entry for this TFD in Tx byte-count array */ |
2439 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len), | 2454 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len), |