diff options
author | dg <dg@FreeBSD.org> | 1995-12-05 11:49:55 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-12-05 11:49:55 +0000 |
commit | 4c3cdc73fb46c7b616f1cd84a0027cd5f4685319 (patch) | |
tree | 4d5fe536f8b02cbb509229fdf516c692c986b869 | |
parent | a17d9df23f1bf98846cd69f58e3710c7ace0ec6e (diff) | |
download | FreeBSD-src-4c3cdc73fb46c7b616f1cd84a0027cd5f4685319.zip FreeBSD-src-4c3cdc73fb46c7b616f1cd84a0027cd5f4685319.tar.gz |
Increased the number of Tx segments from 13 to 29 to reduce the need to
recopy to near zero. Wrote the necessary code to recopy the mbuf chain
into another buffer if there are too many mbufs in the chain.
-rw-r--r-- | sys/dev/fxp/if_fxp.c | 38 | ||||
-rw-r--r-- | sys/dev/fxp/if_fxpreg.h | 4 | ||||
-rw-r--r-- | sys/pci/if_fxp.c | 38 | ||||
-rw-r--r-- | sys/pci/if_fxpreg.h | 4 |
4 files changed, 68 insertions, 16 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 66e2fa0..95a937c 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_fxp.c,v 1.2 1995/12/01 22:41:56 davidg Exp $ + * $Id: if_fxp.c,v 1.3 1995/12/05 02:01:51 davidg Exp $ */ /* @@ -171,9 +171,14 @@ DATA_SET(pcidevice_set, fxp_device); /* * Number of DMA segments in a TxCB. Note that this is carefully - * chosen to make the total struct size an even power of two. + * chosen to make the total struct size an even power of two. It's + * critical that no TxCB be split across a page boundry since + * no attempt is made to allocate physically contiguous memory. + * + * XXX - don't forget to change the hard-coded constant in the + * fxp_cb_tx struct (defined in if_fxpreg.h), too! */ -#define FXP_NTXSEG 13 +#define FXP_NTXSEG 29 /* * Number of receive frame area buffers. These are large so chose @@ -449,6 +454,7 @@ txloop: * the transmit buffers descriptors with the physical address * and size of the mbuf. */ +tbdinit: for (m = mb_head, segment = 0; m != NULL; m = m->m_next) { if (m->m_len != 0) { if (segment == FXP_NTXSEG) @@ -460,14 +466,34 @@ txloop: } } if (m != NULL && segment == FXP_NTXSEG) { + struct mbuf *mn; + /* * We ran out of segments. We have to recopy this mbuf * chain first. */ - panic("fxp%d: ran out of segments", ifp->if_unit); - } else { - txp->tbd_number = segment; + MGETHDR(mn, M_DONTWAIT, MT_DATA); + if (mn == NULL) { + m_freem(mb_head); + return; + } + if (mb_head->m_pkthdr.len > MHLEN) { + MCLGET(mn, M_DONTWAIT); + if ((mn->m_flags & M_EXT) == 0) { + m_freem(mn); + m_freem(mb_head); + return; + } + } + m_copydata(mb_head, 0, mb_head->m_pkthdr.len, mtod(mn, caddr_t)); + mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len; + m_freem(mb_head); + mb_head = mn; + goto tbdinit; } + + txp->tbd_number = segment; + /* * Finish the initialization of this TxCB. */ diff --git a/sys/dev/fxp/if_fxpreg.h b/sys/dev/fxp/if_fxpreg.h index 61c3a5f..7c7b81d 100644 --- a/sys/dev/fxp/if_fxpreg.h +++ b/sys/dev/fxp/if_fxpreg.h @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: if_fxpreg.h,v 1.1 1995/11/28 23:55:26 davidg Exp $ */ #define FXP_VENDORID_INTEL 0x8086 @@ -177,7 +177,7 @@ struct fxp_cb_tx { /* * The following isn't actually part of the TxCB. */ - volatile struct fxp_tbd tbd[13]; + volatile struct fxp_tbd tbd[29]; struct mbuf *mb_head; struct fxp_cb_tx *next; }; diff --git a/sys/pci/if_fxp.c b/sys/pci/if_fxp.c index 66e2fa0..95a937c 100644 --- a/sys/pci/if_fxp.c +++ b/sys/pci/if_fxp.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_fxp.c,v 1.2 1995/12/01 22:41:56 davidg Exp $ + * $Id: if_fxp.c,v 1.3 1995/12/05 02:01:51 davidg Exp $ */ /* @@ -171,9 +171,14 @@ DATA_SET(pcidevice_set, fxp_device); /* * Number of DMA segments in a TxCB. Note that this is carefully - * chosen to make the total struct size an even power of two. + * chosen to make the total struct size an even power of two. It's + * critical that no TxCB be split across a page boundry since + * no attempt is made to allocate physically contiguous memory. + * + * XXX - don't forget to change the hard-coded constant in the + * fxp_cb_tx struct (defined in if_fxpreg.h), too! */ -#define FXP_NTXSEG 13 +#define FXP_NTXSEG 29 /* * Number of receive frame area buffers. These are large so chose @@ -449,6 +454,7 @@ txloop: * the transmit buffers descriptors with the physical address * and size of the mbuf. */ +tbdinit: for (m = mb_head, segment = 0; m != NULL; m = m->m_next) { if (m->m_len != 0) { if (segment == FXP_NTXSEG) @@ -460,14 +466,34 @@ txloop: } } if (m != NULL && segment == FXP_NTXSEG) { + struct mbuf *mn; + /* * We ran out of segments. We have to recopy this mbuf * chain first. */ - panic("fxp%d: ran out of segments", ifp->if_unit); - } else { - txp->tbd_number = segment; + MGETHDR(mn, M_DONTWAIT, MT_DATA); + if (mn == NULL) { + m_freem(mb_head); + return; + } + if (mb_head->m_pkthdr.len > MHLEN) { + MCLGET(mn, M_DONTWAIT); + if ((mn->m_flags & M_EXT) == 0) { + m_freem(mn); + m_freem(mb_head); + return; + } + } + m_copydata(mb_head, 0, mb_head->m_pkthdr.len, mtod(mn, caddr_t)); + mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len; + m_freem(mb_head); + mb_head = mn; + goto tbdinit; } + + txp->tbd_number = segment; + /* * Finish the initialization of this TxCB. */ diff --git a/sys/pci/if_fxpreg.h b/sys/pci/if_fxpreg.h index 61c3a5f..7c7b81d 100644 --- a/sys/pci/if_fxpreg.h +++ b/sys/pci/if_fxpreg.h @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: if_fxpreg.h,v 1.1 1995/11/28 23:55:26 davidg Exp $ */ #define FXP_VENDORID_INTEL 0x8086 @@ -177,7 +177,7 @@ struct fxp_cb_tx { /* * The following isn't actually part of the TxCB. */ - volatile struct fxp_tbd tbd[13]; + volatile struct fxp_tbd tbd[29]; struct mbuf *mb_head; struct fxp_cb_tx *next; }; |