mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-06-06 23:35:16 +08:00
dpaa: Use if_transmit instead of legacy if_start
This avoids a lock contention on the send queue.
This commit is contained in:
parent
a1bad53dc1
commit
5aa6ee55fc
@ -113,108 +113,90 @@ fman_mac_enable_tx_csum(struct mbuf *m, struct qm_fd *fd,
|
|||||||
fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
|
fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
fman_mac_txstart_locked(struct ifnet *ifp, struct fman_mac_softc *sc)
|
fman_mac_tx(struct ifnet *ifp, struct mbuf *m)
|
||||||
{
|
|
||||||
|
|
||||||
FMAN_MAC_ASSERT_LOCKED(sc);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
struct fman_mac_sgt *sgt;
|
|
||||||
struct mbuf *m;
|
|
||||||
struct mbuf *n;
|
|
||||||
struct qm_fd fd;
|
|
||||||
struct dpaa_priv *priv;
|
|
||||||
struct qman_fq *egress_fq;
|
|
||||||
int queue = 0;
|
|
||||||
size_t i;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
|
||||||
if (m == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sgt = uma_zalloc(fman_mac_sgt_zone, M_NOWAIT);
|
|
||||||
if (sgt == NULL) {
|
|
||||||
if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
|
|
||||||
m_freem(m);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
qm_fd_clear_fd(&fd);
|
|
||||||
qm_fd_set_sg(&fd, offsetof(struct fman_mac_sgt, sg), m->m_pkthdr.len);
|
|
||||||
fd.bpid = FSL_DPAA_BPID_INV;
|
|
||||||
fd.cmd |= cpu_to_be32(FM_FD_CMD_FCO);
|
|
||||||
qm_fd_addr_set64(&fd, (uintptr_t)sgt);
|
|
||||||
fman_mac_enable_tx_csum(m, &fd, &sgt->prs);
|
|
||||||
|
|
||||||
repeat_with_collapsed_mbuf_chain:
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
n = m;
|
|
||||||
|
|
||||||
while (n != NULL && i < DPAA_SGT_MAX_ENTRIES) {
|
|
||||||
int len = n->m_len;
|
|
||||||
|
|
||||||
if (len > 0) {
|
|
||||||
qm_sg_entry_set_len(&sgt->sg[i], len);
|
|
||||||
sgt->sg[i].bpid = FSL_DPAA_BPID_INV;
|
|
||||||
sgt->sg[i].offset = 0;
|
|
||||||
qm_sg_entry_set64(&sgt->sg[i],
|
|
||||||
mtod(n, uintptr_t));
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = n->m_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n != NULL && i == DPAA_SGT_MAX_ENTRIES) {
|
|
||||||
struct mbuf *c;
|
|
||||||
|
|
||||||
c = m_collapse(m, M_NOWAIT, DPAA_SGT_MAX_ENTRIES);
|
|
||||||
if (c == NULL) {
|
|
||||||
if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
|
|
||||||
m_freem(m);
|
|
||||||
uma_zfree(fman_mac_sgt_zone, sgt);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m = c;
|
|
||||||
goto repeat_with_collapsed_mbuf_chain;
|
|
||||||
}
|
|
||||||
|
|
||||||
sgt->sg[i - 1].cfg |= cpu_to_be32(QM_SG_FIN);
|
|
||||||
sgt->m = m;
|
|
||||||
priv = netdev_priv(&sc->mac_dev.net_dev);
|
|
||||||
egress_fq = priv->egress_fqs[queue];
|
|
||||||
fd.cmd |= cpu_to_be32(qman_fq_fqid(priv->conf_fqs[queue]));
|
|
||||||
|
|
||||||
for (i = 0; i < DPAA_ENQUEUE_RETRIES; ++i) {
|
|
||||||
err = qman_enqueue(egress_fq, &fd);
|
|
||||||
if (err != -EBUSY) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(err < 0)) {
|
|
||||||
if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
|
|
||||||
m_freem(m);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fman_mac_txstart(struct ifnet *ifp)
|
|
||||||
{
|
{
|
||||||
struct fman_mac_softc *sc;
|
struct fman_mac_softc *sc;
|
||||||
|
struct fman_mac_sgt *sgt;
|
||||||
|
struct mbuf *n;
|
||||||
|
struct qm_fd fd;
|
||||||
|
struct dpaa_priv *priv;
|
||||||
|
struct qman_fq *egress_fq;
|
||||||
|
int queue = 0;
|
||||||
|
size_t i;
|
||||||
|
int err;
|
||||||
|
|
||||||
sc = ifp->if_softc;
|
sc = ifp->if_softc;
|
||||||
|
|
||||||
FMAN_MAC_LOCK(sc);
|
sgt = uma_zalloc(fman_mac_sgt_zone, M_NOWAIT);
|
||||||
fman_mac_txstart_locked(ifp, sc);
|
if (unlikely(sgt == NULL)) {
|
||||||
FMAN_MAC_UNLOCK(sc);
|
if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
|
||||||
|
m_freem(m);
|
||||||
|
return (ENOBUFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
qm_fd_clear_fd(&fd);
|
||||||
|
qm_fd_set_sg(&fd, offsetof(struct fman_mac_sgt, sg), m->m_pkthdr.len);
|
||||||
|
fd.bpid = FSL_DPAA_BPID_INV;
|
||||||
|
fd.cmd |= cpu_to_be32(FM_FD_CMD_FCO);
|
||||||
|
qm_fd_addr_set64(&fd, (uintptr_t)sgt);
|
||||||
|
fman_mac_enable_tx_csum(m, &fd, &sgt->prs);
|
||||||
|
|
||||||
|
repeat_with_collapsed_mbuf_chain:
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
n = m;
|
||||||
|
|
||||||
|
while (n != NULL && i < DPAA_SGT_MAX_ENTRIES) {
|
||||||
|
int len = n->m_len;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
qm_sg_entry_set_len(&sgt->sg[i], len);
|
||||||
|
sgt->sg[i].bpid = FSL_DPAA_BPID_INV;
|
||||||
|
sgt->sg[i].offset = 0;
|
||||||
|
qm_sg_entry_set64(&sgt->sg[i],
|
||||||
|
mtod(n, uintptr_t));
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = n->m_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(n != NULL && i == DPAA_SGT_MAX_ENTRIES)) {
|
||||||
|
struct mbuf *c;
|
||||||
|
|
||||||
|
c = m_collapse(m, M_NOWAIT, DPAA_SGT_MAX_ENTRIES);
|
||||||
|
if (c == NULL) {
|
||||||
|
if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
|
||||||
|
m_freem(m);
|
||||||
|
uma_zfree(fman_mac_sgt_zone, sgt);
|
||||||
|
return (ENOBUFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
m = c;
|
||||||
|
goto repeat_with_collapsed_mbuf_chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
sgt->sg[i - 1].cfg |= cpu_to_be32(QM_SG_FIN);
|
||||||
|
sgt->m = m;
|
||||||
|
priv = netdev_priv(&sc->mac_dev.net_dev);
|
||||||
|
egress_fq = priv->egress_fqs[queue];
|
||||||
|
fd.cmd |= cpu_to_be32(qman_fq_fqid(priv->conf_fqs[queue]));
|
||||||
|
|
||||||
|
for (i = 0; i < DPAA_ENQUEUE_RETRIES; ++i) {
|
||||||
|
err = qman_enqueue(egress_fq, &fd);
|
||||||
|
if (likely(err != -EBUSY)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(err < 0)) {
|
||||||
|
if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
|
||||||
|
m_freem(m);
|
||||||
|
return (ENOBUFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -447,7 +429,8 @@ fman_mac_dev_attach(device_t dev)
|
|||||||
IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
|
IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
|
||||||
ifp->if_capenable = ifp->if_capabilities;
|
ifp->if_capenable = ifp->if_capabilities;
|
||||||
ifp->if_hwassist = FMAN_MAC_CSUM;
|
ifp->if_hwassist = FMAN_MAC_CSUM;
|
||||||
ifp->if_start = fman_mac_txstart;
|
ifp->if_transmit = fman_mac_tx;
|
||||||
|
ifp->if_qflush = if_qflush;
|
||||||
ifp->if_ioctl = fman_mac_ioctl;
|
ifp->if_ioctl = fman_mac_ioctl;
|
||||||
ifp->if_init = fman_mac_init;
|
ifp->if_init = fman_mac_init;
|
||||||
IFQ_SET_MAXLEN(&ifp->if_snd, 128);
|
IFQ_SET_MAXLEN(&ifp->if_snd, 128);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user