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 brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, int prec) { struct sk_buff *p; int eprec = -1; /* precedence to evict from */ bool discard_oldest; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; /* Fast case, precedence queue is not full and we are also not * exceeding total queue length */ if (!pktq_pfull(q, prec) && !pktq_full(q)) { brcmu_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 = brcmu_pktq_peek_tail(q, &eprec); if (eprec > prec) return false; } /* Evict if needed */ if (eprec >= 0) { /* Detect queueing to unconfigured precedence */ discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec); if (eprec == prec && !discard_oldest) return false; /* refuse newer (incoming) packet */ /* Evict packet according to discard policy */ p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : brcmu_pktq_pdeq_tail(q, eprec); if (p == NULL) brcmf_err("brcmu_pktq_penq() failed, oldest %d\n", discard_oldest); brcmu_pkt_buf_free_skb(p); } /* Enqueue */ p = brcmu_pktq_penq(q, prec, pkt); if (p == NULL) brcmf_err("brcmu_pktq_penq() failed\n"); return p != NULL; }
/* * osl multiple-precedence packet queue * hi_prec is always >= the number of the highest non-empty precedence */ struct sk_buff *BCMFASTPATH pktq_penq(struct pktq *pq, int prec, struct sk_buff *p) { struct pktq_prec *q; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(p->prev == NULL); /* queueing chains not allowed */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; if (q->head) q->tail->prev = p; else q->head = p; q->tail = p; q->len++; pq->len++; if (pq->hi_prec < prec) pq->hi_prec = (u8) prec; return p; }
void * BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec, void *p) { struct pktq_prec *q; /* protect shared resource */ if (HND_PKTQ_MUTEX_ACQUIRE(&pq->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS) return NULL; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; if (q->head == NULL) q->tail = p; PKTSETLINK(p, q->head); q->head = p; q->len++; pq->len++; if (pq->hi_prec < prec) pq->hi_prec = (uint8)prec; /* protect shared resource */ if (HND_PKTQ_MUTEX_RELEASE(&pq->mutex) != OSL_EXT_SUCCESS) return NULL; return p; }
void * pktq_penq_head(struct pktq *pq, int prec, void *p) { struct pktq_prec *q; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; if (q->head == NULL) q->tail = p; PKTSETLINK(p, q->head); q->head = p; q->len++; pq->len++; if (pq->hi_prec < prec) pq->hi_prec = (uint8)prec; return p; }
/* * osl multiple-precedence packet queue * hi_prec is always >= the number of the highest non-empty precedence */ void * BCMFASTPATH pktq_penq(struct pktq *pq, int prec, void *p) { struct pktq_prec *q; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; if ((q->head) && (q->tail)) PKTSETLINK(q->tail, p); else q->head = p; q->tail = p; q->len++; pq->len++; if (pq->hi_prec < prec) pq->hi_prec = (uint8)prec; return p; }
/* * osl multiple-precedence packet queue * hi_prec is always >= the number of the highest non-empty precedence */ struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec, struct sk_buff *p) { struct pktq_prec *q; if (pktq_full(pq) || pktq_pfull(pq, prec)) return NULL; q = &pq->q[prec]; if (q->head) q->tail->prev = p; else q->head = p; q->tail = p; q->len++; pq->len++; if (pq->hi_prec < prec) pq->hi_prec = (u8) prec; return p; }
bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, int prec) { struct sk_buff *p; int eprec = -1; bool discard_oldest; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; if (!pktq_pfull(q, prec) && !pktq_full(q)) { brcmu_pktq_penq(q, prec, pkt); return true; } if (pktq_pfull(q, prec)) eprec = prec; else if (pktq_full(q)) { p = brcmu_pktq_peek_tail(q, &eprec); if (eprec > prec) return false; } if (eprec >= 0) { discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec); if (eprec == prec && !discard_oldest) return false; p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : brcmu_pktq_pdeq_tail(q, eprec); if (p == NULL) brcmf_dbg(ERROR, "brcmu_pktq_penq() failed, oldest %d\n", discard_oldest); brcmu_pkt_buf_free_skb(p); } p = brcmu_pktq_penq(q, prec, pkt); if (p == NULL) brcmf_dbg(ERROR, "brcmu_pktq_penq() failed\n"); return p != NULL; }
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; }
void pktenq(struct pktq *q, void *p) { ASSERT(p); ASSERT(!pktq_full(q)); ASSERT(q->p[q->tail] == NULL); q->p[q->tail] = p; q->tail = pktq_next(q->tail); }
/* * Prepend spktq 'list' to the head of pktq 'pq' */ void BCMFASTPATH pktq_prepend(struct pktq *pq, int prec, struct spktq *list) { struct pktq_prec *q; struct pktq_prec *list_q; /* protect shared resource */ if (HND_PKTQ_MUTEX_ACQUIRE(&pq->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS) return; list_q = &list->q[0]; /* empty list check */ if (list_q->head == NULL) goto done; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(PKTLINK(list_q->tail) == NULL); /* terminated list */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; /* set the tail packet of list to point at the former pq head */ PKTSETLINK(list_q->tail, q->head); /* the new q head is the head of list */ q->head = list_q->head; /* If the q tail was non-null, then it stays as is. * If the q tail was null, it is now the tail of list */ if (q->tail == NULL) { q->tail = list_q->tail; } q->len += list_q->len; pq->len += list_q->len; if (pq->hi_prec < prec) pq->hi_prec = (uint8)prec; list_q->head = NULL; list_q->tail = NULL; list_q->len = 0; list->len = 0; done: /* protect shared resource */ if (HND_PKTQ_MUTEX_RELEASE(&pq->mutex) != OSL_EXT_SUCCESS) return; }
/* * Append spktq 'list' to the tail of pktq 'pq' */ void BCMFASTPATH pktq_append(struct pktq *pq, int prec, struct spktq *list) { struct pktq_prec *q; struct pktq_prec *list_q; /* protect shared resource */ if (HND_PKTQ_MUTEX_ACQUIRE(&pq->mutex, OSL_EXT_TIME_FOREVER) != OSL_EXT_SUCCESS) return; list_q = &list->q[0]; /* empty list check */ if (list_q->head == NULL) goto done; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(PKTLINK(list_q->tail) == NULL); /* terminated list */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; if (q->head) PKTSETLINK(q->tail, list_q->head); else q->head = list_q->head; q->tail = list_q->tail; q->len += list_q->len; pq->len += list_q->len; if (pq->hi_prec < prec) pq->hi_prec = (uint8)prec; list_q->head = NULL; list_q->tail = NULL; list_q->len = 0; list->len = 0; done: /* protect shared resource */ if (HND_PKTQ_MUTEX_RELEASE(&pq->mutex) != OSL_EXT_SUCCESS) return; }
struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, struct sk_buff *p) { struct sk_buff_head *q; if (pktq_full(pq) || pktq_pfull(pq, prec)) return NULL; q = &pq->q[prec].skblist; skb_queue_head(q, p); pq->len++; if (pq->hi_prec < prec) pq->hi_prec = (u8) prec; return p; }
/* * Prepend spktq 'list' to the head of pktq 'pq' */ void BCMFASTPATH pktq_prepend(struct pktq *pq, int prec, struct spktq *list) { struct pktq_prec *q; struct pktq_prec *list_q; list_q = &list->q[0]; /* empty list check */ if (list_q->head == NULL) return; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(PKTLINK(list_q->tail) == NULL); /* terminated list */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; /* set the tail packet of list to point at the former pq head */ PKTSETLINK(list_q->tail, q->head); /* the new q head is the head of list */ q->head = list_q->head; /* If the q tail was non-null, then it stays as is. * If the q tail was null, it is now the tail of list */ if (q->tail == NULL) { q->tail = list_q->tail; } q->len += list_q->len; pq->len += list_q->len; if (pq->hi_prec < prec) pq->hi_prec = (uint8)prec; list_q->head = NULL; list_q->tail = NULL; list_q->len = 0; list->len = 0; }
static void bcm_rpc_tp_buf_send_enq(rpc_tp_info_t * rpc_th, rpc_buf_t *b) { pktenq(rpc_th->tx_flowctlq, (void*)b); rpc_th->tx_q_flowctl_segcnt += pktsegcnt(rpc_th->osh, b); /* if hiwm is reached, throttle wldriver * TODO, count more(average 3?) if agg is ON */ if (rpc_th->tx_q_flowctl_segcnt > rpc_th->tx_q_flowctl_hiwm) { rpc_th->tx_q_flowctl_highwm_cnt++; RPC_TP_ERR(("bcm_rpc_tp_buf_send_enq, wm hit high!\n")); rpc_th->txflowctl_cb(rpc_th->txflowctl_ctx, ON); } /* If tx_flowctlq gets full, set a bigger BCM_RPC_TP_Q_MAX */ ASSERT(!pktq_full(rpc_th->tx_flowctlq)); }
/* * Append spktq 'list' to the tail of pktq 'pq' */ void BCMFASTPATH pktq_append(struct pktq *pq, int prec, struct spktq *list) { struct pktq_prec *q; struct pktq_prec *list_q; list_q = &list->q[0]; /* empty list check */ if (list_q->head == NULL) return; ASSERT(prec >= 0 && prec < pq->num_prec); ASSERT(PKTLINK(list_q->tail) == NULL); /* terminated list */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); q = &pq->q[prec]; if (q->head) PKTSETLINK(q->tail, list_q->head); else q->head = list_q->head; q->tail = list_q->tail; q->len += list_q->len; pq->len += list_q->len; if (pq->hi_prec < prec) pq->hi_prec = (uint8)prec; list_q->head = NULL; list_q->tail = NULL; list_q->len = 0; list->len = 0; }
struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, struct sk_buff *p) { struct pktq_prec *q; if (pktq_full(pq) || pktq_pfull(pq, prec)) return NULL; q = &pq->q[prec]; if (q->head == NULL) q->tail = p; p->prev = q->head; q->head = p; q->len++; pq->len++; if (pq->hi_prec < prec) pq->hi_prec = (u8) prec; return p; }