summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-10-31 17:03:06 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-11-02 09:34:39 +0100
commit20e1e769f84089804dc94737c7aff595fc2397de (patch)
tree0288260b4ccf679ab22d717a2b9ad6ed7660e5ff /c
parentlibnetworking: Use system events (diff)
downloadrtems-20e1e769f84089804dc94737c7aff595fc2397de.tar.bz2
bsp/mpc55xx: SMSC9218i avoid mbuf migration
The receive task will only hand over a mbuf if it gets a new one immediately. This avoids mbuf migration out of the receive task in case of overload.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/network/smsc9218i.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/network/smsc9218i.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/network/smsc9218i.c
index 2a03f12133..0747c3dd2d 100644
--- a/c/src/lib/libbsp/powerpc/mpc55xxevb/network/smsc9218i.c
+++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/network/smsc9218i.c
@@ -810,23 +810,37 @@ static void smsc9218i_media_status_change(
smsc9218i_mac_write(regs, SMSC9218I_MAC_CR, mac_cr);
}
-static void smsc9218i_new_mbuf(
+static bool smsc9218i_new_mbuf(
struct ifnet *ifp,
smsc9218i_receive_job_control *jc,
- int i
+ int i,
+ struct mbuf *old_m
)
{
- struct mbuf *m = m_gethdr(M_WAIT, MT_DATA);
+ bool ok = false;
+ int wait = old_m != NULL ? M_DONTWAIT : M_WAIT;
+ struct mbuf *new_m = m_gethdr(wait, MT_DATA);
struct tcd_t *tcd = &jc->tcd_table [i];
char *data = NULL;
- m->m_pkthdr.rcvif = ifp;
- MCLGET(m, M_WAIT);
+ if (new_m != NULL ) {
+ new_m->m_pkthdr.rcvif = ifp;
+ MCLGET(new_m, wait);
- data = mtod(m, char *);
- m->m_data = data + SMSC9218I_RX_DATA_OFFSET + ETHER_HDR_LEN;
+ if ((new_m->m_flags & M_EXT) != 0) {
+ ok = true;
+ } else {
+ m_free(new_m);
+ new_m = old_m;
+ }
+ } else {
+ new_m = old_m;
+ }
- jc->mbuf_table [i] = m;
+ data = mtod(new_m, char *);
+ new_m->m_data = data + SMSC9218I_RX_DATA_OFFSET + ETHER_HDR_LEN;
+
+ jc->mbuf_table [i] = new_m;
tcd->DADDR = (uint32_t) data;
tcd->BMF.R = SMSC9218I_TCD_BMF_LINK;
@@ -836,6 +850,8 @@ static void smsc9218i_new_mbuf(
data,
SMSC9218I_RX_DATA_OFFSET + ETHER_HDR_LEN + ETHERMTU + ETHER_CRC_LEN
);
+
+ return ok;
}
static void smsc9218i_init_receive_jobs(
@@ -868,7 +884,7 @@ static void smsc9218i_init_receive_jobs(
tcd->CDF.B.DOFF = 4;
tcd->DLAST_SGA = (int32_t) next_tcd;
- smsc9218i_new_mbuf(ifp, jc, i);
+ smsc9218i_new_mbuf(ifp, jc, i, NULL);
}
}
@@ -889,8 +905,9 @@ static void smsc9218i_ether_input(
(mtod(m, char *) - ETHER_HDR_LEN);
++e->received_frames;
- ether_input(ifp, eh, m);
- smsc9218i_new_mbuf(ifp, jc, c);
+ if (smsc9218i_new_mbuf(ifp, jc, c, m)) {
+ ether_input(ifp, eh, m);
+ }
c = (c + 1) % SMSC9218I_RX_JOBS;
}