if_de.c (149476) | if_de.c (149497) |
---|---|
1/* $NetBSD: if_de.c,v 1.86 1999/06/01 19:17:59 thorpej Exp $ */ 2/*- 3 * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 22 unchanged lines hidden (view full) --- 31 * Written by Matt Thomas 32 * BPF support code stolen directly from if_ec.c 33 * 34 * This driver supports the DEC DE435 or any other PCI 35 * board which support 21040, 21041, or 21140 (mostly). 36 */ 37 38#include <sys/cdefs.h> | 1/* $NetBSD: if_de.c,v 1.86 1999/06/01 19:17:59 thorpej Exp $ */ 2/*- 3 * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 22 unchanged lines hidden (view full) --- 31 * Written by Matt Thomas 32 * BPF support code stolen directly from if_ec.c 33 * 34 * This driver supports the DEC DE435 or any other PCI 35 * board which support 21040, 21041, or 21140 (mostly). 36 */ 37 38#include <sys/cdefs.h> |
39__FBSDID("$FreeBSD: head/sys/dev/de/if_de.c 149476 2005-08-25 21:06:56Z jhb $"); | 39__FBSDID("$FreeBSD: head/sys/dev/de/if_de.c 149497 2005-08-26 14:27:38Z jhb $"); |
40 41#define TULIP_HDR_DATA 42 43#include "opt_ddb.h" 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/endian.h> --- 3359 unchanged lines hidden (view full) --- 3407 me, dip - ri->ri_first); 3408 } 3409 KASSERT(dip == eop, ("mismatched descinfo structs")); 3410 } 3411 3412 /* 3413 * Now get the size of received packet (minus the CRC). 3414 */ | 40 41#define TULIP_HDR_DATA 42 43#include "opt_ddb.h" 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/endian.h> --- 3359 unchanged lines hidden (view full) --- 3407 me, dip - ri->ri_first); 3408 } 3409 KASSERT(dip == eop, ("mismatched descinfo structs")); 3410 } 3411 3412 /* 3413 * Now get the size of received packet (minus the CRC). 3414 */ |
3415 total_len = ((DESC_STATUS(eop) >> 16) & 0x7FFF) - 4; | 3415 total_len = ((DESC_STATUS(eop) >> 16) & 0x7FFF) - ETHER_CRC_LEN; |
3416 if ((sc->tulip_flags & TULIP_RXIGNORE) == 0 3417 && ((DESC_STATUS(eop) & TULIP_DSTS_ERRSUM) == 0)) { 3418 me->m_len = total_len - last_offset; 3419 sc->tulip_flags |= TULIP_RXACT; 3420 accept = 1; 3421 CTR1(KTR_TULIP, "tulip_rx_intr: good packet; length %d", 3422 total_len); 3423 } else { --- 40 unchanged lines hidden (view full) --- 3464 cnt++; 3465#endif 3466 ifp->if_ipackets++; 3467 if (++eop == ri->ri_last) 3468 eop = ri->ri_first; 3469 ri->ri_nextin = eop; 3470 queue_mbuf: 3471 /* | 3416 if ((sc->tulip_flags & TULIP_RXIGNORE) == 0 3417 && ((DESC_STATUS(eop) & TULIP_DSTS_ERRSUM) == 0)) { 3418 me->m_len = total_len - last_offset; 3419 sc->tulip_flags |= TULIP_RXACT; 3420 accept = 1; 3421 CTR1(KTR_TULIP, "tulip_rx_intr: good packet; length %d", 3422 total_len); 3423 } else { --- 40 unchanged lines hidden (view full) --- 3464 cnt++; 3465#endif 3466 ifp->if_ipackets++; 3467 if (++eop == ri->ri_last) 3468 eop = ri->ri_first; 3469 ri->ri_nextin = eop; 3470 queue_mbuf: 3471 /* |
3472 * Either we are priming the TULIP with mbufs (m == NULL) 3473 * or we are about to accept an mbuf for the upper layers 3474 * so we need to allocate an mbuf to replace it. If we 3475 * can't replace it, send up it anyways. This may cause 3476 * us to drop packets in the future but that's better than 3477 * being caught in livelock. 3478 * 3479 * Note that if this packet crossed multiple descriptors 3480 * we don't even try to reallocate all the mbufs here. 3481 * Instead we rely on the test at the beginning of 3482 * the loop to refill for the extra consumed mbufs. | 3472 * We have received a good packet that needs to be passed up the 3473 * stack. |
3483 */ | 3474 */ |
3484 if (accept || ms == NULL) { | 3475 if (accept) { |
3485 struct mbuf *m0; 3486 | 3476 struct mbuf *m0; 3477 |
3478 KASSERT(ms != NULL, ("no packet to accept")); |
|
3487#if defined(TULIP_COPY_RXDATA) | 3479#if defined(TULIP_COPY_RXDATA) |
3488 if (!accept || total_len >= (MHLEN - 2)) 3489 m0 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 3490 else 3491 MGETHDR(m0, M_DONTWAIT, MT_DATA); 3492 if (accept && m0 != NULL) { 3493 TULIP_UNLOCK(sc); 3494 m0->m_data += 2; /* align data after header */ 3495 m_copydata(ms, 0, total_len, mtod(m0, caddr_t)); 3496 m0->m_len = m0->m_pkthdr.len = total_len; 3497 m0->m_pkthdr.rcvif = ifp; 3498 CTR1(KTR_TULIP, "tulip_rx_intr: passing %p to upper layer", m0); 3499 (*ifp->if_input)(ifp, m0); 3500 m0 = ms; 3501 TULIP_LOCK(sc); | 3480 /* 3481 * Copy the data into a new mbuf that is properly aligned. If 3482 * we fail to allocate a new mbuf, then drop the packet. We will 3483 * reuse the same rx buffer ('ms') below for another packet 3484 * regardless. 3485 */ 3486 m0 = m_devget(mtod(ms, caddr_t), total_len, ETHER_ALIGN, ifp, NULL); 3487 if (m0 == NULL) { 3488 ifp->if_ierrors++; 3489 goto skip_input; |
3502 } | 3490 } |
3503#else /* TULIP_COPY_RXDATA */ 3504 m0 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 3505 if (accept) { 3506 TULIP_UNLOCK(sc); 3507 ms->m_pkthdr.len = total_len; 3508 ms->m_pkthdr.rcvif = ifp; 3509 CTR1(KTR_TULIP, "tulip_rx_intr: passing %p to upper layer", ms); 3510 (*ifp->if_input)(ifp, ms); 3511 TULIP_LOCK(sc); 3512 } 3513#endif /* TULIP_COPY_RXDATA */ 3514 ms = m0; 3515 } | 3491#else 3492 /* 3493 * Update the header for the mbuf referencing this receive 3494 * buffer and pass it up the stack. Allocate a new mbuf cluster 3495 * to replace the one we just passed up the stack. 3496 * 3497 * Note that if this packet crossed multiple descriptors 3498 * we don't even try to reallocate all the mbufs here. 3499 * Instead we rely on the test at the beginning of 3500 * the loop to refill for the extra consumed mbufs. 3501 */ 3502 ms->m_pkthdr.len = total_len; 3503 ms->m_pkthdr.rcvif = ifp; 3504 m0 = ms; 3505 ms = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 3506#endif 3507 TULIP_UNLOCK(sc); 3508 CTR1(KTR_TULIP, "tulip_rx_intr: passing %p to upper layer", m0); 3509 (*ifp->if_input)(ifp, m0); 3510 TULIP_LOCK(sc); 3511 } else if (ms == NULL) 3512 /* 3513 * If we are priming the TULIP with mbufs, then allocate 3514 * a new cluster for the next descriptor. 3515 */ 3516 ms = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 3517 3518#if defined(TULIP_COPY_RXDATA) 3519 skip_input: 3520#endif |
3516 if (ms == NULL) { 3517 /* 3518 * Couldn't allocate a new buffer. Don't bother 3519 * trying to replenish the receive queue. 3520 */ 3521 fillok = 0; 3522 sc->tulip_flags |= TULIP_RXBUFSLOW; 3523#if defined(TULIP_DEBUG) --- 339 unchanged lines hidden (view full) --- 3863 TULIP_LOCK(sc); 3864#if defined(TULIP_DEBUG) 3865 sc->tulip_dbg.dbg_intrs++; 3866#endif 3867 tulip_intr_handler(sc); 3868 TULIP_UNLOCK(sc); 3869} 3870 | 3521 if (ms == NULL) { 3522 /* 3523 * Couldn't allocate a new buffer. Don't bother 3524 * trying to replenish the receive queue. 3525 */ 3526 fillok = 0; 3527 sc->tulip_flags |= TULIP_RXBUFSLOW; 3528#if defined(TULIP_DEBUG) --- 339 unchanged lines hidden (view full) --- 3868 TULIP_LOCK(sc); 3869#if defined(TULIP_DEBUG) 3870 sc->tulip_dbg.dbg_intrs++; 3871#endif 3872 tulip_intr_handler(sc); 3873 TULIP_UNLOCK(sc); 3874} 3875 |
3871CTASSERT(MCLBYTES >= ETHERMTU + 18); 3872 | |
3873static struct mbuf * | 3876static struct mbuf * |
3874tulip_mbuf_compress(struct mbuf *m) 3875{ 3876 struct mbuf *m0; 3877 3878 if (m->m_pkthdr.len > MHLEN) 3879 m0 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 3880 else 3881 MGETHDR(m0, M_DONTWAIT, MT_DATA); 3882 if (m0 != NULL) { 3883 m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t)); 3884 m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len; 3885 } 3886 m_freem(m); 3887 return m0; 3888} 3889 3890static struct mbuf * | |
3891tulip_txput(tulip_softc_t * const sc, struct mbuf *m) 3892{ 3893 TULIP_PERFSTART(txput) 3894 tulip_ringinfo_t * const ri = &sc->tulip_txinfo; 3895 tulip_descinfo_t *eop, *nextout; 3896 int segcnt, free; 3897 u_int32_t d_status; 3898 bus_dma_segment_t segs[TULIP_MAX_TXSEG]; 3899 bus_dmamap_t *map; 3900 int error, nsegs; | 3877tulip_txput(tulip_softc_t * const sc, struct mbuf *m) 3878{ 3879 TULIP_PERFSTART(txput) 3880 tulip_ringinfo_t * const ri = &sc->tulip_txinfo; 3881 tulip_descinfo_t *eop, *nextout; 3882 int segcnt, free; 3883 u_int32_t d_status; 3884 bus_dma_segment_t segs[TULIP_MAX_TXSEG]; 3885 bus_dmamap_t *map; 3886 int error, nsegs; |
3901#if defined(KTR) && KTR_TULIP 3902 struct mbuf *m1; 3903#endif | 3887 struct mbuf *m0; |
3904 3905 TULIP_LOCK_ASSERT(sc); 3906#if defined(TULIP_DEBUG) 3907 if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) { 3908 if_printf(sc->tulip_ifp, "txput%s: tx not running\n", 3909 (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : ""); 3910 sc->tulip_flags |= TULIP_WANTTXSTART; 3911 sc->tulip_dbg.dbg_txput_finishes[0]++; --- 15 unchanged lines hidden (view full) --- 3927 * We may fail to put the entire packet on the ring if 3928 * there is either not enough ring entries free or if the 3929 * packet has more than MAX_TXSEG segments. In the former 3930 * case we will just wait for the ring to empty. In the 3931 * latter case we have to recopy. 3932 */ 3933#if defined(KTR) && KTR_TULIP 3934 segcnt = 1; | 3888 3889 TULIP_LOCK_ASSERT(sc); 3890#if defined(TULIP_DEBUG) 3891 if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) { 3892 if_printf(sc->tulip_ifp, "txput%s: tx not running\n", 3893 (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : ""); 3894 sc->tulip_flags |= TULIP_WANTTXSTART; 3895 sc->tulip_dbg.dbg_txput_finishes[0]++; --- 15 unchanged lines hidden (view full) --- 3911 * We may fail to put the entire packet on the ring if 3912 * there is either not enough ring entries free or if the 3913 * packet has more than MAX_TXSEG segments. In the former 3914 * case we will just wait for the ring to empty. In the 3915 * latter case we have to recopy. 3916 */ 3917#if defined(KTR) && KTR_TULIP 3918 segcnt = 1; |
3935 m1 = m; 3936 while (m1->m_next != NULL) { | 3919 m0 = m; 3920 while (m0->m_next != NULL) { |
3937 segcnt++; | 3921 segcnt++; |
3938 m1 = m1->m_next; | 3922 m0 = m0->m_next; |
3939 } 3940#endif 3941 CTR2(KTR_TULIP, "tulip_txput: sending packet %p (%d chunks)", m, segcnt); 3942 d_status = 0; 3943 eop = nextout = ri->ri_nextout; 3944 segcnt = 0; 3945 free = ri->ri_free; 3946 --- 16 unchanged lines hidden (view full) --- 3963 } 3964 error = bus_dmamap_load_mbuf_sg(ri->ri_data_tag, *eop->di_map, m, segs, 3965 &nsegs, BUS_DMA_NOWAIT); 3966 if (error != 0) { 3967 if (error == EFBIG) { 3968 /* 3969 * The packet exceeds the number of transmit buffer 3970 * entries that we can use for one packet, so we have | 3923 } 3924#endif 3925 CTR2(KTR_TULIP, "tulip_txput: sending packet %p (%d chunks)", m, segcnt); 3926 d_status = 0; 3927 eop = nextout = ri->ri_nextout; 3928 segcnt = 0; 3929 free = ri->ri_free; 3930 --- 16 unchanged lines hidden (view full) --- 3947 } 3948 error = bus_dmamap_load_mbuf_sg(ri->ri_data_tag, *eop->di_map, m, segs, 3949 &nsegs, BUS_DMA_NOWAIT); 3950 if (error != 0) { 3951 if (error == EFBIG) { 3952 /* 3953 * The packet exceeds the number of transmit buffer 3954 * entries that we can use for one packet, so we have |
3971 * to recopy it into one mbuf and then try again. | 3955 * to recopy it into one mbuf and then try again. If 3956 * we can't recopy it, try again later. |
3972 */ | 3957 */ |
3973 m = tulip_mbuf_compress(m); 3974 if (m == NULL) { | 3958 m0 = m_defrag(m, M_DONTWAIT); 3959 if (m0 == NULL) { 3960 sc->tulip_flags |= TULIP_WANTTXSTART; |
3975#if defined(TULIP_DEBUG) 3976 sc->tulip_dbg.dbg_txput_finishes[2]++; 3977#endif 3978 goto finish; 3979 } | 3961#if defined(TULIP_DEBUG) 3962 sc->tulip_dbg.dbg_txput_finishes[2]++; 3963#endif 3964 goto finish; 3965 } |
3966 m = m0; |
|
3980 error = bus_dmamap_load_mbuf_sg(ri->ri_data_tag, *eop->di_map, m, 3981 segs, &nsegs, BUS_DMA_NOWAIT); 3982 } 3983 if (error != 0) { 3984 if_printf(sc->tulip_ifp, 3985 "unable to load tx map, error = %d\n", error); 3986#if defined(TULIP_DEBUG) 3987 sc->tulip_dbg.dbg_txput_finishes[3]++; --- 1086 unchanged lines hidden --- | 3967 error = bus_dmamap_load_mbuf_sg(ri->ri_data_tag, *eop->di_map, m, 3968 segs, &nsegs, BUS_DMA_NOWAIT); 3969 } 3970 if (error != 0) { 3971 if_printf(sc->tulip_ifp, 3972 "unable to load tx map, error = %d\n", error); 3973#if defined(TULIP_DEBUG) 3974 sc->tulip_dbg.dbg_txput_finishes[3]++; --- 1086 unchanged lines hidden --- |