| .. | .. |
|---|
| 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 | |
|---|