bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, int prec) { struct sk_buff *p; int eprec = -1; /* precedence to evict from */ bool discard_oldest; /* Fast case, precedence queue is not full and we are also not * exceeding total queue length */ if (!pktq_pfull(q, prec) && !pktq_full(q)) { bcm_pktq_penq(q, prec, pkt); return true; } /* Determine precedence from which to evict packet, if any */ if (pktq_pfull(q, prec)) eprec = prec; else if (pktq_full(q)) { p = bcm_pktq_peek_tail(q, &eprec); ASSERT(p); if (eprec > prec) return false; } /* Evict if needed */ if (eprec >= 0) { /* Detect queueing to unconfigured precedence */ ASSERT(!pktq_pempty(q, eprec)); discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec); if (eprec == prec && !discard_oldest) return false; /* refuse newer (incoming) packet */ /* Evict packet according to discard policy */ p = discard_oldest ? bcm_pktq_pdeq(q, eprec) : bcm_pktq_pdeq_tail(q, eprec); if (p == NULL) { DHD_ERROR(("%s: bcm_pktq_penq() failed, oldest %d.", __func__, discard_oldest)); ASSERT(p); } bcm_pkt_buf_free_skb(p); } /* Enqueue */ p = bcm_pktq_penq(q, prec, pkt); if (p == NULL) { DHD_ERROR(("%s: bcm_pktq_penq() failed.", __func__)); ASSERT(p); } return true; }
bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec) { void *p; int eprec = -1; /* precedence to evict from */ bool discard_oldest; /* Fast case, precedence queue is not full and we are also not * exceeding total queue length */ if (!pktq_pfull(q, prec) && !pktq_full(q)) { pktq_penq(q, prec, pkt); return TRUE; } /* Determine precedence from which to evict packet, if any */ if (pktq_pfull(q, prec)) eprec = prec; else if (pktq_full(q)) { p = pktq_peek_tail(q, &eprec); ASSERT(p); if (eprec > prec) return FALSE; } /* Evict if needed */ if (eprec >= 0) { /* Detect queueing to unconfigured precedence */ ASSERT(!pktq_pempty(q, eprec)); discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec); if (eprec == prec && !discard_oldest) return FALSE; /* refuse newer (incoming) packet */ /* Evict packet according to discard policy */ p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, eprec); ASSERT(p); PKTFREE(dhdp->osh, p, TRUE); } /* Enqueue */ p = pktq_penq(q, prec, pkt); ASSERT(p); return TRUE; }