aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-11-12 11:12:05 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-11-24 01:30:17 -0500
commiteb96ccb138fccdedd76c773e476e4a6ce4b3c05c (patch)
treeacf40978d95ca13d50801f56d1378ce58cea4ee8
parentd0963b5d31cabf98afba1599c73324ce036cd081 (diff)
iwlwifi: mvm: pull crypto header into skb->head
When we pre-populate the skb->head for the stack, we only pull in the 802.11 header (assuming the packet isn't short enough to be in there completely.) This is fine, but in many cases we'll pull in the crypto headers pretty much immediately afterwards, so to avoid that pull in the crypto header early. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Reviewed-by: IdoX Yariv <ido@wizery.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 57052e67ceb8..69fa765e29b5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -98,16 +98,16 @@ int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
98static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, 98static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
99 struct sk_buff *skb, 99 struct sk_buff *skb,
100 struct ieee80211_hdr *hdr, u16 len, 100 struct ieee80211_hdr *hdr, u16 len,
101 u32 ampdu_status, 101 u32 ampdu_status, u8 crypt_len,
102 struct iwl_rx_cmd_buffer *rxb) 102 struct iwl_rx_cmd_buffer *rxb)
103{ 103{
104 unsigned int hdrlen, fraglen; 104 unsigned int hdrlen, fraglen;
105 105
106 /* If frame is small enough to fit in skb->head, pull it completely. 106 /* If frame is small enough to fit in skb->head, pull it completely.
107 * If not, only pull ieee80211_hdr so that splice() or TCP coalesce 107 * If not, only pull ieee80211_hdr (including crypto if present) so
108 * are more efficient. 108 * that splice() or TCP coalesce are more efficient.
109 */ 109 */
110 hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr); 110 hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr) + crypt_len;
111 111
112 memcpy(skb_put(skb, hdrlen), hdr, hdrlen); 112 memcpy(skb_put(skb, hdrlen), hdr, hdrlen);
113 fraglen = len - hdrlen; 113 fraglen = len - hdrlen;
@@ -174,7 +174,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
174static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm, 174static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
175 struct ieee80211_hdr *hdr, 175 struct ieee80211_hdr *hdr,
176 struct ieee80211_rx_status *stats, 176 struct ieee80211_rx_status *stats,
177 u32 rx_pkt_status) 177 u32 rx_pkt_status,
178 u8 *crypt_len)
178{ 179{
179 if (!ieee80211_has_protected(hdr->frame_control) || 180 if (!ieee80211_has_protected(hdr->frame_control) ||
180 (rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) == 181 (rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) ==
@@ -194,12 +195,14 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
194 195
195 stats->flag |= RX_FLAG_DECRYPTED; 196 stats->flag |= RX_FLAG_DECRYPTED;
196 IWL_DEBUG_WEP(mvm, "hw decrypted CCMP successfully\n"); 197 IWL_DEBUG_WEP(mvm, "hw decrypted CCMP successfully\n");
198 *crypt_len = IEEE80211_CCMP_HDR_LEN;
197 return 0; 199 return 0;
198 200
199 case RX_MPDU_RES_STATUS_SEC_TKIP_ENC: 201 case RX_MPDU_RES_STATUS_SEC_TKIP_ENC:
200 /* Don't drop the frame and decrypt it in SW */ 202 /* Don't drop the frame and decrypt it in SW */
201 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK)) 203 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK))
202 return 0; 204 return 0;
205 *crypt_len = IEEE80211_TKIP_IV_LEN;
203 /* fall through if TTAK OK */ 206 /* fall through if TTAK OK */
204 207
205 case RX_MPDU_RES_STATUS_SEC_WEP_ENC: 208 case RX_MPDU_RES_STATUS_SEC_WEP_ENC:
@@ -207,6 +210,9 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
207 return -1; 210 return -1;
208 211
209 stats->flag |= RX_FLAG_DECRYPTED; 212 stats->flag |= RX_FLAG_DECRYPTED;
213 if ((rx_pkt_status & RX_MPDU_RES_STATUS_SEC_ENC_MSK) ==
214 RX_MPDU_RES_STATUS_SEC_WEP_ENC)
215 *crypt_len = IEEE80211_WEP_IV_LEN;
210 return 0; 216 return 0;
211 217
212 case RX_MPDU_RES_STATUS_SEC_EXT_ENC: 218 case RX_MPDU_RES_STATUS_SEC_EXT_ENC:
@@ -241,6 +247,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
241 u32 ampdu_status; 247 u32 ampdu_status;
242 u32 rate_n_flags; 248 u32 rate_n_flags;
243 u32 rx_pkt_status; 249 u32 rx_pkt_status;
250 u8 crypt_len = 0;
244 251
245 phy_info = &mvm->last_phy_info; 252 phy_info = &mvm->last_phy_info;
246 rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data; 253 rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data;
@@ -263,7 +270,8 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
263 /* 270 /*
264 * drop the packet if it has failed being decrypted by HW 271 * drop the packet if it has failed being decrypted by HW
265 */ 272 */
266 if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, rx_status, rx_pkt_status)) { 273 if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, rx_status, rx_pkt_status,
274 &crypt_len)) {
267 IWL_DEBUG_DROP(mvm, "Bad decryption results 0x%08x\n", 275 IWL_DEBUG_DROP(mvm, "Bad decryption results 0x%08x\n",
268 rx_pkt_status); 276 rx_pkt_status);
269 kfree_skb(skb); 277 kfree_skb(skb);
@@ -393,7 +401,8 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
393 iwl_mvm_update_frame_stats(mvm, &mvm->drv_rx_stats, rate_n_flags, 401 iwl_mvm_update_frame_stats(mvm, &mvm->drv_rx_stats, rate_n_flags,
394 rx_status->flag & RX_FLAG_AMPDU_DETAILS); 402 rx_status->flag & RX_FLAG_AMPDU_DETAILS);
395#endif 403#endif
396 iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status, rxb); 404 iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status,
405 crypt_len, rxb);
397 return 0; 406 return 0;
398} 407}
399 408