/* * Allocate and add an object to packet pool. */ void * osl_ctfpool_add(osl_t *osh) { struct sk_buff *skb; #ifdef CTFPOOL_SPINLOCK unsigned long flags; #endif /* CTFPOOL_SPINLOCK */ if ((osh == NULL) || (osh->ctfpool == NULL)) return NULL; CTFPOOL_LOCK(osh->ctfpool, flags); ASSERT(osh->ctfpool->curr_obj <= osh->ctfpool->max_obj); /* No need to allocate more objects */ if (osh->ctfpool->curr_obj == osh->ctfpool->max_obj) { CTFPOOL_UNLOCK(osh->ctfpool, flags); return NULL; } /* Allocate a new skb and add it to the ctfpool */ skb = osl_alloc_skb(osh->ctfpool->obj_size); if (skb == NULL) { printf("%s: skb alloc of len %d failed\n", __FUNCTION__, osh->ctfpool->obj_size); CTFPOOL_UNLOCK(osh->ctfpool, flags); return NULL; } /* Add to ctfpool */ skb->next = (struct sk_buff *)osh->ctfpool->head; osh->ctfpool->head = skb; osh->ctfpool->fast_frees++; osh->ctfpool->curr_obj++; /* Hijack a skb member to store ptr to ctfpool */ CTFPOOLPTR(osh, skb) = (void *)osh->ctfpool; /* Use bit flag to indicate skb from fast ctfpool */ PKTFAST(osh, skb) = FASTBUF; CTFPOOL_UNLOCK(osh->ctfpool, flags); return skb; }
void * osl_ctfpool_add(osl_t *osh) { struct sk_buff *skb; #ifdef CTFPOOL_SPINLOCK unsigned long flags; #endif if ((osh == NULL) || (osh->ctfpool == NULL)) return NULL; CTFPOOL_LOCK(osh->ctfpool, flags); ASSERT(osh->ctfpool->curr_obj <= osh->ctfpool->max_obj); if (osh->ctfpool->curr_obj == osh->ctfpool->max_obj) { CTFPOOL_UNLOCK(osh->ctfpool, flags); return NULL; } skb = osl_alloc_skb(osh->ctfpool->obj_size); if (skb == NULL) { printf("%s: skb alloc of len %d failed\n", __FUNCTION__, osh->ctfpool->obj_size); CTFPOOL_UNLOCK(osh->ctfpool, flags); return NULL; } skb->next = (struct sk_buff *)osh->ctfpool->head; osh->ctfpool->head = skb; osh->ctfpool->fast_frees++; osh->ctfpool->curr_obj++; CTFPOOLPTR(osh, skb) = (void *)osh->ctfpool; PKTFAST(osh, skb) = FASTBUF; CTFPOOL_UNLOCK(osh->ctfpool, flags); return skb; }
void * osl_pktdup(osl_t *osh, void *skb) { void * p; ASSERT(!PKTISCHAINED(skb)); PKTCTFMAP(osh, skb); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) if ((p = pskb_copy((struct sk_buff *)skb, GFP_ATOMIC)) == NULL) #else if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL) #endif return NULL; #ifdef CTFPOOL if (PKTISFAST(osh, skb)) { ctfpool_t *ctfpool; ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); ASSERT(ctfpool != NULL); PKTCLRFAST(osh, p); PKTCLRFAST(osh, skb); ctfpool->refills++; } #endif PKTSETCLINK(p, NULL); PKTCCLRFLAGS(p); PKTCSETCNT(p, 1); PKTCSETLEN(p, PKTLEN(osh, skb)); if (osh->pub.pkttag) OSL_PKTTAG_CLEAR(p); atomic_inc(&osh->pktalloced); return (p); }
void * osl_ctfpool_add(osl_t *osh) { struct sk_buff *skb; if ((osh == NULL) || (osh->ctfpool == NULL)) return NULL; spin_lock_bh(&osh->ctfpool->lock); ASSERT(osh->ctfpool->curr_obj <= osh->ctfpool->max_obj); if (osh->ctfpool->curr_obj == osh->ctfpool->max_obj) { spin_unlock_bh(&osh->ctfpool->lock); return NULL; } skb = osl_alloc_skb(osh->ctfpool->obj_size); if (skb == NULL) { printf("%s: skb alloc of len %d failed\n", __FUNCTION__, osh->ctfpool->obj_size); spin_unlock_bh(&osh->ctfpool->lock); return NULL; } skb->next = (struct sk_buff *)osh->ctfpool->head; osh->ctfpool->head = skb; osh->ctfpool->fast_frees++; osh->ctfpool->curr_obj++; CTFPOOLPTR(osh, skb) = (void *)osh->ctfpool; PKTFAST(osh, skb) = FASTBUF; spin_unlock_bh(&osh->ctfpool->lock); return skb; }
/* * Allocate and add an object to packet pool. */ void * osl_ctfpool_add(osl_t *osh) { struct sk_buff *skb; if ((osh == NULL) || (osh->ctfpool == NULL)) return NULL; spin_lock_bh(&osh->ctfpool->lock); ASSERT(osh->ctfpool->curr_obj <= osh->ctfpool->max_obj); /* No need to allocate more objects */ if (osh->ctfpool->curr_obj == osh->ctfpool->max_obj) { spin_unlock_bh(&osh->ctfpool->lock); return NULL; } /* Allocate a new skb and add it to the ctfpool */ skb = dev_alloc_skb(osh->ctfpool->obj_size); if (skb == NULL) { OSL_MSG_ERROR(("%s: skb alloc of len %d failed\n", __FUNCTION__, osh->ctfpool->obj_size)); spin_unlock_bh(&osh->ctfpool->lock); return NULL; } /* Add to ctfpool */ skb->next = (struct sk_buff *)osh->ctfpool->head; osh->ctfpool->head = skb; osh->ctfpool->fast_frees++; osh->ctfpool->curr_obj++; /* Hijack a skb member to store ptr to ctfpool */ CTFPOOLPTR(osh, skb) = (void *)osh->ctfpool; /* Use bit flag to indicate skb from fast ctfpool */ PKTFAST(osh, skb) = FASTBUF; spin_unlock_bh(&osh->ctfpool->lock); return skb; }
void * osl_pktdup(osl_t *osh, void *skb) { void * p; unsigned long irqflags; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) gfp_t flags; #endif PKTCTFMAP(osh, skb); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; if ((p = skb_clone((struct sk_buff *)skb, flags)) == NULL) #else if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL) #endif return NULL; #ifdef CTFPOOL if (PKTISFAST(osh, skb)) { ctfpool_t *ctfpool; ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); ASSERT(ctfpool != NULL); PKTCLRFAST(osh, p); PKTCLRFAST(osh, skb); ctfpool->refills++; } #endif if (osh->pub.pkttag) bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); spin_lock_irqsave(&osh->pktalloc_lock, irqflags); osh->pub.pktalloced++; spin_unlock_irqrestore(&osh->pktalloc_lock, irqflags); return (p); }
/* Clone a packet. * The pkttag contents are NOT cloned. */ void * osl_pktdup(osl_t *osh, void *skb) { void * p; ASSERT(!PKTISCHAINED(skb)); /* clear the CTFBUF flag if set and map the rest of the buffer * before cloning. */ PKTCTFMAP(osh, skb); if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL) return NULL; #ifdef CTFPOOL if (PKTISFAST(osh, skb)) { ctfpool_t *ctfpool; /* if the buffer allocated from ctfpool is cloned then * we can't be sure when it will be freed. since there * is a chance that we will be losing a buffer * from our pool, we increment the refill count for the * object to be alloced later. */ ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); ASSERT(ctfpool != NULL); PKTCLRFAST(osh, p); PKTCLRFAST(osh, skb); ctfpool->refills++; } #endif /* CTFPOOL */ /* skb_clone copies skb->cb.. we don't want that */ if (osh->pub.pkttag) OSL_PKTTAG_CLEAR(p); /* Increment the packet counter */ atomic_inc(&osh->pktalloced); return (p); }
void * osl_pktdup(osl_t *osh, void *skb) { void * p; ASSERT(!PKTISCHAINED(skb)); PKTCTFMAP(osh, skb); if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL) return NULL; #ifdef CTFPOOL if (PKTISFAST(osh, skb)) { ctfpool_t *ctfpool; ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); ASSERT(ctfpool != NULL); PKTCLRFAST(osh, p); PKTCLRFAST(osh, skb); ctfpool->refills++; } #endif PKTSETCLINK(p, NULL); PKTCCLRATTR(p); if (osh->pub.pkttag) OSL_PKTTAG_CLEAR(p); atomic_inc(&osh->pktalloced); return (p); }
void * BCMFASTPATH osl_pktget(osl_t *osh, uint len) { struct sk_buff *skb; #ifdef CTFPOOL skb = osl_pktfastget(osh, len); if ((skb != NULL) || ((skb = osl_alloc_skb(osh, len)) != NULL)) { #else if ((skb = osl_alloc_skb(osh, len))) { #endif skb->tail += len; skb->len += len; skb->priority = 0; atomic_inc(&osh->pktalloced); } return ((void*) skb); } #ifdef CTFPOOL static inline void osl_pktfastfree(osl_t *osh, struct sk_buff *skb) { ctfpool_t *ctfpool; #ifdef CTFPOOL_SPINLOCK unsigned long flags; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) skb->tstamp.tv.sec = 0; #else skb->stamp.tv_sec = 0; #endif skb->dev = NULL; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) skb->dst = NULL; #endif OSL_PKTTAG_CLEAR(skb); skb->ip_summed = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) skb_orphan(skb); #else skb->destructor = NULL; #endif ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); ASSERT(ctfpool != NULL); CTFPOOL_LOCK(ctfpool, flags); skb->next = (struct sk_buff *)ctfpool->head; ctfpool->head = (void *)skb; ctfpool->fast_frees++; ctfpool->curr_obj++; ASSERT(ctfpool->curr_obj <= ctfpool->max_obj); CTFPOOL_UNLOCK(ctfpool, flags); }
void * BCMFASTPATH osl_pktget(osl_t *osh, uint len) { struct sk_buff *skb; unsigned long flags; #ifdef CTFPOOL skb = osl_pktfastget(osh, len); if ((skb != NULL) || ((skb = osl_alloc_skb(len)) != NULL)) { #else if ((skb = osl_alloc_skb(len))) { #endif skb_put(skb, len); skb->priority = 0; spin_lock_irqsave(&osh->pktalloc_lock, flags); osh->pub.pktalloced++; spin_unlock_irqrestore(&osh->pktalloc_lock, flags); } return ((void*) skb); } #ifdef CTFPOOL static inline void osl_pktfastfree(osl_t *osh, struct sk_buff *skb) { ctfpool_t *ctfpool; #ifdef CTFPOOL_SPINLOCK unsigned long flags; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) skb->tstamp.tv.sec = 0; #else skb->stamp.tv_sec = 0; #endif skb->dev = NULL; skb->dst = NULL; memset(skb->cb, 0, sizeof(skb->cb)); skb->ip_summed = 0; skb->destructor = NULL; ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); ASSERT(ctfpool != NULL); CTFPOOL_LOCK(ctfpool, flags); skb->next = (struct sk_buff *)ctfpool->head; ctfpool->head = (void *)skb; ctfpool->fast_frees++; ctfpool->curr_obj++; ASSERT(ctfpool->curr_obj <= ctfpool->max_obj); CTFPOOL_UNLOCK(ctfpool, flags); }
/* Return a new packet. zero out pkttag */ void * BCMFASTPATH osl_pktget(osl_t *osh, uint len) { struct sk_buff *skb; #ifdef CTFPOOL /* Allocate from local pool */ skb = osl_pktfastget(osh, len); if ((skb != NULL) || ((skb = osl_alloc_skb(len)) != NULL)) { #else /* CTFPOOL */ if ((skb = osl_alloc_skb(len))) { #endif /* CTFPOOL */ skb_put(skb, len); skb->priority = 0; atomic_inc(&osh->pktalloced); } return ((void*) skb); } #ifdef CTFPOOL static inline void osl_pktfastfree(osl_t *osh, struct sk_buff *skb) { ctfpool_t *ctfpool; #ifdef CTFPOOL_SPINLOCK unsigned long flags; #endif /* CTFPOOL_SPINLOCK */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) skb->tstamp.tv64 = 0; #else skb->stamp.tv_sec = 0; #endif /* We only need to init the fields that we change */ skb->dev = NULL; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) skb->dst = NULL; #endif OSL_PKTTAG_CLEAR(skb); skb->ip_summed = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) skb_orphan(skb); #else skb->destructor = NULL; #endif ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); // ASSERT(ctfpool != NULL); if (ctfpool == NULL) return; /* Add object to the ctfpool */ CTFPOOL_LOCK(ctfpool, flags); skb->next = (struct sk_buff *)ctfpool->head; ctfpool->head = (void *)skb; ctfpool->fast_frees++; ctfpool->curr_obj++; ASSERT(ctfpool->curr_obj <= ctfpool->max_obj); CTFPOOL_UNLOCK(ctfpool, flags); }