コード例 #1
0
ファイル: ndshared.c プロジェクト: NemProjects/WLAN
/* add a page worth of packets to a freelist */
NDIS_STATUS
shared_lb_addpage(
	IN shared_info_t *shared,
	IN struct lbfree *l,
	IN BOOLEAN piomode,
	page_t *page,
	IN uint ipp,
	IN uint lbdatasz
)
{
	struct lbuf *lb;
	char *va;
	ULONG pa;
	uint i;

	ASSERT(l->npages < (ROUNDUP(l->total, ipp) / ipp));

	/* add it to the page list */
	l->pages[l->npages] = *page;
	l->npages++;

	/*
	 * Split each page into one or more LBUFSZ chunks,
	 * link them together, and put each on the freelist.
	 */

	va = page->va;
	pa = page->pa.LowPart;

	for (i = 0; i < ipp; i++) {
		char *vbuf = NULL;
		uint pbuf = 0;
		lb = (struct lbuf*)(va + lbdatasz);
		if (lbdatasz) {
			vbuf = va;
			pbuf = pa;
		}

		/* initialize lbuf fields */
		lb->link = lb->next = NULL;
		lb->head = lb->data = lb->tail = vbuf;
		lb->end = (uchar*)lb;
		lb->len = 0;
		lb->pa = piomode? 0xdeadbeef: pbuf;
		lb->p = NULL;
		lb->l = l;

		/* put it on the freelist */
		shared_lb_put(shared, l, lb);

		if (lbdatasz) {
			va += LBUFSZ;
			pa += LBUFSZ;
		} else
			va += sizeof(struct lbuf);
	}

	return (NDIS_STATUS_SUCCESS);
}
コード例 #2
0
ファイル: ndshared.c プロジェクト: NemProjects/WLAN
/* bust apart and free an rx ndis packet and buffer descriptor and lbuf */
void
shared_free_ndispacket(
	IN shared_info_t *shared,
	IN ND_PKT *p
)
{
	struct lbuf *lb;

	/* pick the associated lbuf off the ndis packet */
	lb = (struct lbuf*) NEXTP(p);
	ASSERT(lb);
	ASSERT(lb->p == p);
	NEXTP(p) = NULL;
	lb->p = NULL;

	/* free the ndis packet and buffer descriptors */
	shared_free_pkt(p);

	/* put our lbuf back on the freelist */
	shared_lb_put(shared, lb->l, lb);
}
コード例 #3
0
static void BCMFASTPATH
bcm_rpc_tp_pktfree(rpc_tp_info_t * rpcb, rpc_buf_t *b, bool send)
{
	uint32 free_cnt = 0;
#if defined(NDIS)
	struct lbuf *lb = (struct lbuf*)b;
	struct lbuf *next;

	ASSERT(rpcb);

	ASSERT(lb != NULL);

	do {
		next = lb->next;
		lb->next = NULL;
		ASSERT(lb->p == NULL);

		shared_lb_put(rpcb->sh, lb->l, lb);

		free_cnt++;
		lb = next;
	} while (lb);

#else
	struct sk_buff *skb = (struct sk_buff*)b, *next;

#if defined(CTFPOOL)
	next = skb;
	while (next != NULL) {
		next = next->next;
		free_cnt++;
	}

	PKTFREE(rpcb->osh, skb, FALSE);
#else
	while (skb) {
		next = skb->next;

		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);
		}
		skb = next;
		free_cnt++;
	}
#endif /* defined(CTFPOOL) */

	RPC_TP_LOCK(rpcb);
	rpcb->buf_cnt_inuse -= free_cnt;

	if (rpcb->rxflowctrl && (rpcb->buf_cnt_inuse < RPCRX_WM_LO)) {
		rpcb->rxflowctrl = FALSE;
		RPC_TP_ERR(("%s, rxflowctrl change to %d\n", __FUNCTION__, rpcb->rxflowctrl));
		dbus_flowctrl_rx(rpcb->bus, FALSE);
	}

	RPC_TP_UNLOCK(rpcb);
#endif /* NDIS */

}