.. | .. |
---|
1203 | 1203 | struct sk_buff_head mpdus_skbs; |
---|
1204 | 1204 | unsigned int payload_len; |
---|
1205 | 1205 | int ret; |
---|
| 1206 | + struct sk_buff *orig_skb = skb; |
---|
1206 | 1207 | |
---|
1207 | 1208 | if (WARN_ON_ONCE(!mvmsta)) |
---|
1208 | 1209 | return -1; |
---|
.. | .. |
---|
1235 | 1236 | |
---|
1236 | 1237 | ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta); |
---|
1237 | 1238 | if (ret) { |
---|
| 1239 | + /* Free skbs created as part of TSO logic that have not yet been dequeued */ |
---|
1238 | 1240 | __skb_queue_purge(&mpdus_skbs); |
---|
1239 | | - return ret; |
---|
| 1241 | + /* skb here is not necessarily same as skb that entered this method, |
---|
| 1242 | + * so free it explicitly. |
---|
| 1243 | + */ |
---|
| 1244 | + if (skb == orig_skb) |
---|
| 1245 | + ieee80211_free_txskb(mvm->hw, skb); |
---|
| 1246 | + else |
---|
| 1247 | + kfree_skb(skb); |
---|
| 1248 | + /* there was error, but we consumed skb one way or another, so return 0 */ |
---|
| 1249 | + return 0; |
---|
1240 | 1250 | } |
---|
1241 | 1251 | } |
---|
1242 | 1252 | |
---|