Implemented packet (de)queueing. Unused, etharp.c must be adapted next.

This commit is contained in:
likewise 2003-05-01 07:48:01 +00:00
parent 084c45d3db
commit a0eb47d561

View File

@ -2,14 +2,21 @@
* @file * @file
* Packet buffer management * Packet buffer management
* *
* Packets are represented by the pbuf data structure. It supports dynamic * Packets are built from the pbuf data structure. It supports dynamic
* memory allocation for packet contents or can reference externally * memory allocation for packet contents or can reference externally
* managed packet contents both in RAM and ROM. Quick allocation for * managed packet contents both in RAM and ROM. Quick allocation for
* incoming packets is provided through pools with fixed sized pbufs. * incoming packets is provided through pools with fixed sized pbufs.
* *
* Pbufs can be chained as a singly linked list, called a pbuf chain, so * A packet may span over multiple pbufs, chained as a singly linked
* that a packet may span over several pbufs. * list. This is called a "pbuf chain".
* *
* Multiple packets may be queued using this singly linked list. This
* is called a "pbuf queue". So, a pbuf queue consists of one or more
* pbuf chains, each of which consist of one or more pbufs.
*
* In order to find the last pbuf of a packet, traverse the linked list
* until the ->tot_len field equals the ->len field. If the ->next field
* of this packet is not NULL, more packets are on the queue.
*/ */
/* /*
@ -607,33 +614,15 @@ pbuf_ref(struct pbuf *p)
/** /**
* *
* Increment the reference count of all pbufs in a chain. * Chain two pbufs (or pbuf chains) together. They must belong to the same packet.
*
* @param p first pbuf of chain
*
*/
void
pbuf_ref_chain(struct pbuf *p)
{
SYS_ARCH_DECL_PROTECT(old_level);
SYS_ARCH_PROTECT(old_level);
while (p != NULL) {
++p->ref;
p = p->next;
}
SYS_ARCH_UNPROTECT(old_level);
}
/**
*
* Link two pbufs (or chains) together.
* *
* @param h head pbuf (chain) * @param h head pbuf (chain)
* @param t tail pbuf (chain) * @param t tail pbuf (chain)
* *
* The ->tot_len field of the first pbuf (h) is adjusted. * The ->tot_len fields of all pbufs of the head chain are adjusted.
* The ->next field of the last pbuf of the head chain is adjusted.
* The ->ref field of the first pbuf of the tail chain is adjusted.
*
*/ */
void void
pbuf_chain(struct pbuf *h, struct pbuf *t) pbuf_chain(struct pbuf *h, struct pbuf *t)
@ -652,6 +641,7 @@ pbuf_chain(struct pbuf *h, struct pbuf *t)
p->tot_len += t->tot_len; p->tot_len += t->tot_len;
} }
/* p is last pbuf of first h chain */ /* p is last pbuf of first h chain */
LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
/* add total length of second chain to last pbuf total of first chain */ /* add total length of second chain to last pbuf total of first chain */
p->tot_len += t->tot_len; p->tot_len += t->tot_len;
/* chain last pbuf of h chain (p) with first of tail (t) */ /* chain last pbuf of h chain (p) with first of tail (t) */
@ -661,12 +651,81 @@ pbuf_chain(struct pbuf *h, struct pbuf *t)
DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: referencing tail %p\n", (void *) t)); DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: referencing tail %p\n", (void *) t));
} }
/* TODO: Will be enabled soon. Please review code. */
#if 1
/**
* Add a packet to the end of a queue.
*
* @param q pointer to first packet on the queue
* @param n packet to be queued
*
*/
void
pbuf_queue(struct pbuf *p, struct pbuf *n)
{
LWIP_ASSERT("p != NULL", p != NULL);
LWIP_ASSERT("n != NULL", n != NULL);
if ((p == NULL) || (n == NULL))
return;
/* iterate through all packets on queue */
while (p->next != NULL) {
/* be very picky about pbuf chain correctness */
#if PBUF_DEBUG
/* iterate through all pbufs in packet */
while (p->tot_len != p->len) {
/* make sure each packet is complete */
LWIP_ASSERT("p->next != NULL", p->next != NULL);
p = p->next;
}
#endif
p = p->next;
}
/* chain last pbuf of h chain (p) with first of tail (t) */
p->next = n;
/* t is now referenced to one more time */
pbuf_ref(n);
DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_queue: referencing queued packet %p\n", (void *)n));
}
/**
* Remove a packet from the head of a queue.
*
* @param p pointer to first packet on the queue which will be dequeued.
* @return first packet on the remaining queue (NULL if no further packets).
*
*/
struct pbuf *
pbuf_dequeue(struct pbuf *p)
{
struct pbuf *q;
LWIP_ASSERT("p != NULL", p != NULL);
/* iterate through all pbufs in packet */
while (p->tot_len != p->len) {
/* make sure each packet is complete */
LWIP_ASSERT("p->next != NULL", p->next != NULL);
p = p->next;
}
/* remember next packet on queue */
q = p->next;
/* dequeue p from queue */
p->next = NULL;
/* q is now referenced to one less time */
pbuf_free(q);
DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: dereferencing remaining queue%p\n", (void *)q));
return q;
}
#endif
/** /**
* *
* Create PBUF_POOL (or PBUF_RAM) copies of PBUF_REF pbufs. * Create PBUF_POOL (or PBUF_RAM) copies of PBUF_REF pbufs.
* *
* Used to queue packets on behalf of the lwIP stack, such as
* ARP based queueing.
*
* Go through a pbuf chain and replace any PBUF_REF buffers * Go through a pbuf chain and replace any PBUF_REF buffers
* with PBUF_POOL (or PBUF_RAM) pbufs, each taking a copy of * with PBUF_POOL (or PBUF_RAM) pbufs, each taking a copy of
* the referenced data. * the referenced data.
@ -676,13 +735,11 @@ pbuf_chain(struct pbuf *h, struct pbuf *t)
* by pbuf_take()! * by pbuf_take()!
* *
* @note Any replaced pbufs will be freed through pbuf_free(). * @note Any replaced pbufs will be freed through pbuf_free().
* * This may allocate them if they become no longer referenced.
* Used to queue packets on behalf of the lwIP stack, such as
* ARP based queueing.
* *
* @param p Head of pbuf chain to process * @param p Head of pbuf chain to process
* *
* @return Pointer to new head of pbuf chain * @return Pointer to head of pbuf chain
*/ */
struct pbuf * struct pbuf *
pbuf_take(struct pbuf *p) pbuf_take(struct pbuf *p)
@ -767,7 +824,7 @@ pbuf_take(struct pbuf *p)
return head; return head;
} }
#if 0 /* expected to enabled again, once needed (multiple chain queueing comes to mind) */ #if 0 /* TODO: See if we might need this for future features */
/** /**
* Dechains the first pbuf from its succeeding pbufs in the chain. * Dechains the first pbuf from its succeeding pbufs in the chain.
* *
@ -802,3 +859,27 @@ pbuf_dechain(struct pbuf *p)
return (tail_gone > 0? NULL: q); return (tail_gone > 0? NULL: q);
} }
#endif /* pbuf_dechain() */ #endif /* pbuf_dechain() */
/* TODO: This function is unused in the lwIP stack and will be deprecated. This is due
* to the new way chains are built. */
#if 0
/**
*
* Increment the reference count of all pbufs in a chain.
*
* @param p first pbuf of chain
*
*/
void
pbuf_ref_chain(struct pbuf *p)
{
SYS_ARCH_DECL_PROTECT(old_level);
SYS_ARCH_PROTECT(old_level);
while (p != NULL) {
++p->ref;
p = p->next;
}
SYS_ARCH_UNPROTECT(old_level);
}
#endif