/* Free the driver packet. Free the tag if present */ void osl_pktfree(osl_t *osh, void *p, bool send) { struct sk_buff *skb, *nskb; pktfree_cb_fn_t tx_fn = osh->pub.tx_fn; skb = (struct sk_buff*) p; if (send && tx_fn) tx_fn(osh->pub.tx_ctx, p, 0); /* perversion: we use skb->next to chain multi-skb packets */ while (skb) { nskb = skb->next; skb->next = NULL; #ifdef BCMDBG_PKT pktlist_remove(&(osh->pktlist), (void *) skb); #endif /* BCMDBG_PKT */ if (skb->destructor) { /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ dev_kfree_skb_any(skb); } else { /* can free immediately (even in_irq()) if destructor does not exist */ dev_kfree_skb(skb); } osh->pub.pktalloced--; skb = nskb; } }
void osl_pktfree(osl_t *osh, void *p, bool send) { struct sk_buff *skb, *nskb; skb = (struct sk_buff*) p; if (send && osh->pub.tx_fn) osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); while (skb) { nskb = skb->next; skb->next = NULL; #ifdef BCMDBG_PKT pktlist_remove(&(osh->pktlist), (void *) skb); #endif if (skb->destructor) { dev_kfree_skb_any(skb); } else { dev_kfree_skb(skb); } osh->pub.pktalloced--; skb = nskb; } }
struct sk_buff * osl_pkt_tonative(osl_t *osh, void *pkt) { struct sk_buff *nskb; if (osh->pub.pkttag) bzero((void*)((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ); for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { #ifdef BCMDBG_PKT pktlist_remove(&(osh->pktlist), (void *) nskb); #endif osh->pub.pktalloced--; } return (struct sk_buff *)pkt; }
/* Free the driver packet. Free the tag if present */ void osl_pktfree(osl_t *osh, void *p, bool send) { struct sk_buff *skb, *nskb; skb = (struct sk_buff*) p; if (send && osh->pub.tx_fn) osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); /* perversion: we use skb->next to chain multi-skb packets */ while (skb) { nskb = skb->next; skb->next = NULL; #ifdef BCMDBG_PKT pktlist_remove(&(osh->pktlist), (void *) skb); #endif /* BCMDBG_PKT */ #ifdef DSLCPE if (((struct sk_buff *)skb)->retfreeq_cb && (((struct sk_buff *)skb)->retfreeq_flags & SKB_DATA_PREALLOC)) { osh->pub.pktbuffered--; } dev_kfree_skb_any(skb); #else if (skb->destructor) { /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ dev_kfree_skb_any(skb); } else { /* can free immediately (even in_irq()) if destructor does not exist */ dev_kfree_skb(skb); } #endif osh->pub.pktalloced--; skb = nskb; } }
void osl_pktlist_remove(osl_t *osh, void *p) { pktlist_remove(&(osh->pktlist), p); }