diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00crypto.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00crypto.c | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index ae31581372c0..57ab42cfed34 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c | |||
@@ -65,7 +65,7 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | |||
65 | __set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags); | 65 | __set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags); |
66 | 66 | ||
67 | txdesc->key_idx = hw_key->hw_key_idx; | 67 | txdesc->key_idx = hw_key->hw_key_idx; |
68 | txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb); | 68 | txdesc->iv_offset = txdesc->header_length; |
69 | txdesc->iv_len = hw_key->iv_len; | 69 | txdesc->iv_len = hw_key->iv_len; |
70 | 70 | ||
71 | if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) | 71 | if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) |
@@ -132,17 +132,16 @@ void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc) | |||
132 | skb_pull(skb, txdesc->iv_len); | 132 | skb_pull(skb, txdesc->iv_len); |
133 | 133 | ||
134 | /* IV/EIV data has officially be stripped */ | 134 | /* IV/EIV data has officially be stripped */ |
135 | skbdesc->flags |= FRAME_DESC_IV_STRIPPED; | 135 | skbdesc->flags |= SKBDESC_IV_STRIPPED; |
136 | } | 136 | } |
137 | 137 | ||
138 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb) | 138 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length) |
139 | { | 139 | { |
140 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 140 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
141 | unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb); | ||
142 | const unsigned int iv_len = | 141 | const unsigned int iv_len = |
143 | ((!!(skbdesc->iv[0])) * 4) + ((!!(skbdesc->iv[1])) * 4); | 142 | ((!!(skbdesc->iv[0])) * 4) + ((!!(skbdesc->iv[1])) * 4); |
144 | 143 | ||
145 | if (!(skbdesc->flags & FRAME_DESC_IV_STRIPPED)) | 144 | if (!(skbdesc->flags & SKBDESC_IV_STRIPPED)) |
146 | return; | 145 | return; |
147 | 146 | ||
148 | skb_push(skb, iv_len); | 147 | skb_push(skb, iv_len); |
@@ -154,14 +153,15 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb) | |||
154 | memcpy(skb->data + header_length, skbdesc->iv, iv_len); | 153 | memcpy(skb->data + header_length, skbdesc->iv, iv_len); |
155 | 154 | ||
156 | /* IV/EIV data has returned into the frame */ | 155 | /* IV/EIV data has returned into the frame */ |
157 | skbdesc->flags &= ~FRAME_DESC_IV_STRIPPED; | 156 | skbdesc->flags &= ~SKBDESC_IV_STRIPPED; |
158 | } | 157 | } |
159 | 158 | ||
160 | void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, | 159 | void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad, |
161 | unsigned int header_length, | 160 | unsigned int header_length, |
162 | struct rxdone_entry_desc *rxdesc) | 161 | struct rxdone_entry_desc *rxdesc) |
163 | { | 162 | { |
164 | unsigned int payload_len = rxdesc->size - header_length; | 163 | unsigned int payload_len = rxdesc->size - header_length; |
164 | unsigned int align = ALIGN_SIZE(skb, header_length); | ||
165 | unsigned int iv_len; | 165 | unsigned int iv_len; |
166 | unsigned int icv_len; | 166 | unsigned int icv_len; |
167 | unsigned int transfer = 0; | 167 | unsigned int transfer = 0; |
@@ -191,32 +191,48 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, | |||
191 | } | 191 | } |
192 | 192 | ||
193 | /* | 193 | /* |
194 | * Make room for new data, note that we increase both | 194 | * Make room for new data. There are 2 possibilities |
195 | * headsize and tailsize when required. The tailsize is | 195 | * either the alignment is already present between |
196 | * only needed when ICV data needs to be inserted and | 196 | * the 802.11 header and payload. In that case we |
197 | * the padding is smaller than the ICV data. | 197 | * we have to move the header less then the iv_len |
198 | * When alignment requirements is greater than the | 198 | * since we can use the already available l2pad bytes |
199 | * ICV data we must trim the skb to the correct size | 199 | * for the iv data. |
200 | * because we need to remove the extra bytes. | 200 | * When the alignment must be added manually we must |
201 | * move the header more then iv_len since we must | ||
202 | * make room for the payload move as well. | ||
201 | */ | 203 | */ |
202 | skb_push(skb, iv_len + align); | 204 | if (l2pad) { |
203 | if (align < icv_len) | 205 | skb_push(skb, iv_len - align); |
204 | skb_put(skb, icv_len - align); | 206 | skb_put(skb, icv_len); |
205 | else if (align > icv_len) | ||
206 | skb_trim(skb, rxdesc->size + iv_len + icv_len); | ||
207 | 207 | ||
208 | /* Move ieee80211 header */ | 208 | /* Move ieee80211 header */ |
209 | memmove(skb->data + transfer, | 209 | memmove(skb->data + transfer, |
210 | skb->data + transfer + iv_len + align, | 210 | skb->data + transfer + (iv_len - align), |
211 | header_length); | 211 | header_length); |
212 | transfer += header_length; | 212 | transfer += header_length; |
213 | } else { | ||
214 | skb_push(skb, iv_len + align); | ||
215 | if (align < icv_len) | ||
216 | skb_put(skb, icv_len - align); | ||
217 | else if (align > icv_len) | ||
218 | skb_trim(skb, rxdesc->size + iv_len + icv_len); | ||
219 | |||
220 | /* Move ieee80211 header */ | ||
221 | memmove(skb->data + transfer, | ||
222 | skb->data + transfer + iv_len + align, | ||
223 | header_length); | ||
224 | transfer += header_length; | ||
225 | } | ||
213 | 226 | ||
214 | /* Copy IV/EIV data */ | 227 | /* Copy IV/EIV data */ |
215 | memcpy(skb->data + transfer, rxdesc->iv, iv_len); | 228 | memcpy(skb->data + transfer, rxdesc->iv, iv_len); |
216 | transfer += iv_len; | 229 | transfer += iv_len; |
217 | 230 | ||
218 | /* Move payload */ | 231 | /* |
219 | if (align) { | 232 | * Move payload for alignment purposes. Note that |
233 | * this is only needed when no l2 padding is present. | ||
234 | */ | ||
235 | if (!l2pad) { | ||
220 | memmove(skb->data + transfer, | 236 | memmove(skb->data + transfer, |
221 | skb->data + transfer + align, | 237 | skb->data + transfer + align, |
222 | payload_len); | 238 | payload_len); |