if_npe.c (259342) | if_npe.c (266406) |
---|---|
1/*- 2 * Copyright (c) 2006-2008 Sam Leffler. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 9 unchanged lines hidden (view full) --- 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2006-2008 Sam Leffler. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 9 unchanged lines hidden (view full) --- 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25#include <sys/cdefs.h> |
26__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/ixp425/if_npe.c 259342 2013-12-13 22:08:31Z ian $"); | 26__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/ixp425/if_npe.c 266406 2014-05-18 16:07:35Z ian $"); |
27 28/* 29 * Intel XScale NPE Ethernet driver. 30 * 31 * This driver handles the two ports present on the IXP425. 32 * Packet processing is done by the Network Processing Engines 33 * (NPE's) that work together with a MAC and PHY. The MAC 34 * is also mapped to the XScale cpu; the PHY is accessed via --- 468 unchanged lines hidden (view full) --- 503 nbuf * sizeof(struct npehwbuf), 0, 504 busdma_lock_mutex, &sc->sc_mtx, &dma->buf_tag); 505 if (error != 0) { 506 device_printf(sc->sc_dev, 507 "unable to create %s npebuf dma tag, error %u\n", 508 dma->name, error); 509 return error; 510 } | 27 28/* 29 * Intel XScale NPE Ethernet driver. 30 * 31 * This driver handles the two ports present on the IXP425. 32 * Packet processing is done by the Network Processing Engines 33 * (NPE's) that work together with a MAC and PHY. The MAC 34 * is also mapped to the XScale cpu; the PHY is accessed via --- 468 unchanged lines hidden (view full) --- 503 nbuf * sizeof(struct npehwbuf), 0, 504 busdma_lock_mutex, &sc->sc_mtx, &dma->buf_tag); 505 if (error != 0) { 506 device_printf(sc->sc_dev, 507 "unable to create %s npebuf dma tag, error %u\n", 508 dma->name, error); 509 return error; 510 } |
511 /* XXX COHERENT for now */ | |
512 if (bus_dmamem_alloc(dma->buf_tag, (void **)&dma->hwbuf, 513 BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, 514 &dma->buf_map) != 0) { 515 device_printf(sc->sc_dev, 516 "unable to allocate memory for %s h/w buffers, error %u\n", 517 dma->name, error); 518 return error; 519 } --- 549 unchanged lines hidden (view full) --- 1069 if (m == NULL) 1070 return ENOBUFS; 1071 } 1072 KASSERT(m->m_ext.ext_size >= 1536 + ETHER_ALIGN, 1073 ("ext_size %d", m->m_ext.ext_size)); 1074 m->m_pkthdr.len = m->m_len = 1536; 1075 /* backload payload and align ip hdr */ 1076 m->m_data = m->m_ext.ext_buf + (m->m_ext.ext_size - (1536+ETHER_ALIGN)); | 511 if (bus_dmamem_alloc(dma->buf_tag, (void **)&dma->hwbuf, 512 BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, 513 &dma->buf_map) != 0) { 514 device_printf(sc->sc_dev, 515 "unable to allocate memory for %s h/w buffers, error %u\n", 516 dma->name, error); 517 return error; 518 } --- 549 unchanged lines hidden (view full) --- 1068 if (m == NULL) 1069 return ENOBUFS; 1070 } 1071 KASSERT(m->m_ext.ext_size >= 1536 + ETHER_ALIGN, 1072 ("ext_size %d", m->m_ext.ext_size)); 1073 m->m_pkthdr.len = m->m_len = 1536; 1074 /* backload payload and align ip hdr */ 1075 m->m_data = m->m_ext.ext_buf + (m->m_ext.ext_size - (1536+ETHER_ALIGN)); |
1076 bus_dmamap_unload(dma->mtag, npe->ix_map); |
|
1077 error = bus_dmamap_load_mbuf_sg(dma->mtag, npe->ix_map, m, 1078 segs, &nseg, 0); 1079 if (error != 0) { 1080 m_freem(m); 1081 return error; 1082 } 1083 hw = npe->ix_hw; 1084 hw->ix_ne[0].data = htobe32(segs[0].ds_addr); 1085 /* NB: NPE requires length be a multiple of 64 */ 1086 /* NB: buffer length is shifted in word */ 1087 hw->ix_ne[0].len = htobe32(segs[0].ds_len << 16); 1088 hw->ix_ne[0].next = 0; | 1077 error = bus_dmamap_load_mbuf_sg(dma->mtag, npe->ix_map, m, 1078 segs, &nseg, 0); 1079 if (error != 0) { 1080 m_freem(m); 1081 return error; 1082 } 1083 hw = npe->ix_hw; 1084 hw->ix_ne[0].data = htobe32(segs[0].ds_addr); 1085 /* NB: NPE requires length be a multiple of 64 */ 1086 /* NB: buffer length is shifted in word */ 1087 hw->ix_ne[0].len = htobe32(segs[0].ds_len << 16); 1088 hw->ix_ne[0].next = 0; |
1089 bus_dmamap_sync(dma->buf_tag, dma->buf_map, 1090 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); |
|
1089 npe->ix_m = m; 1090 /* Flush the memory in the mbuf */ 1091 bus_dmamap_sync(dma->mtag, npe->ix_map, BUS_DMASYNC_PREREAD); 1092 return 0; 1093} 1094 1095/* 1096 * RX q processing for a specific NPE. Claim entries --- 9 unchanged lines hidden (view full) --- 1106 struct npedma *dma = &sc->rxdma; 1107 uint32_t entry; 1108 int rx_npkts = 0; 1109 1110 while (ixpqmgr_qread(qid, &entry) == 0) { 1111 struct npebuf *npe = P2V(NPE_QM_Q_ADDR(entry), dma); 1112 struct mbuf *m; 1113 | 1091 npe->ix_m = m; 1092 /* Flush the memory in the mbuf */ 1093 bus_dmamap_sync(dma->mtag, npe->ix_map, BUS_DMASYNC_PREREAD); 1094 return 0; 1095} 1096 1097/* 1098 * RX q processing for a specific NPE. Claim entries --- 9 unchanged lines hidden (view full) --- 1108 struct npedma *dma = &sc->rxdma; 1109 uint32_t entry; 1110 int rx_npkts = 0; 1111 1112 while (ixpqmgr_qread(qid, &entry) == 0) { 1113 struct npebuf *npe = P2V(NPE_QM_Q_ADDR(entry), dma); 1114 struct mbuf *m; 1115 |
1116 bus_dmamap_sync(dma->buf_tag, dma->buf_map, 1117 BUS_DMASYNC_POSTREAD); |
|
1114 DPRINTF(sc, "%s: entry 0x%x neaddr 0x%x ne_len 0x%x\n", 1115 __func__, entry, npe->ix_neaddr, npe->ix_hw->ix_ne[0].len); 1116 /* 1117 * Allocate a new mbuf to replenish the rx buffer. 1118 * If doing so fails we drop the rx'd frame so we 1119 * can reuse the previous mbuf. When we're able to 1120 * allocate a new mbuf dispatch the mbuf w/ rx'd 1121 * data up the stack and replace it with the newly --- 4 unchanged lines hidden (view full) --- 1126 struct mbuf *mrx = npe->ix_m; 1127 struct npehwbuf *hw = npe->ix_hw; 1128 struct ifnet *ifp = sc->sc_ifp; 1129 1130 /* Flush mbuf memory for rx'd data */ 1131 bus_dmamap_sync(dma->mtag, npe->ix_map, 1132 BUS_DMASYNC_POSTREAD); 1133 | 1118 DPRINTF(sc, "%s: entry 0x%x neaddr 0x%x ne_len 0x%x\n", 1119 __func__, entry, npe->ix_neaddr, npe->ix_hw->ix_ne[0].len); 1120 /* 1121 * Allocate a new mbuf to replenish the rx buffer. 1122 * If doing so fails we drop the rx'd frame so we 1123 * can reuse the previous mbuf. When we're able to 1124 * allocate a new mbuf dispatch the mbuf w/ rx'd 1125 * data up the stack and replace it with the newly --- 4 unchanged lines hidden (view full) --- 1130 struct mbuf *mrx = npe->ix_m; 1131 struct npehwbuf *hw = npe->ix_hw; 1132 struct ifnet *ifp = sc->sc_ifp; 1133 1134 /* Flush mbuf memory for rx'd data */ 1135 bus_dmamap_sync(dma->mtag, npe->ix_map, 1136 BUS_DMASYNC_POSTREAD); 1137 |
1134 /* XXX flush hw buffer; works now 'cuz coherent */ | |
1135 /* set m_len etc. per rx frame size */ 1136 mrx->m_len = be32toh(hw->ix_ne[0].len) & 0xffff; 1137 mrx->m_pkthdr.len = mrx->m_len; 1138 mrx->m_pkthdr.rcvif = ifp; 1139 1140 ifp->if_ipackets++; 1141 ifp->if_input(ifp, mrx); 1142 rx_npkts++; --- 166 unchanged lines hidden (view full) --- 1309 while (sc->tx_free != NULL) { 1310 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1311 if (m == NULL) { 1312 /* XXX? */ 1313 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1314 return; 1315 } 1316 npe = sc->tx_free; | 1138 /* set m_len etc. per rx frame size */ 1139 mrx->m_len = be32toh(hw->ix_ne[0].len) & 0xffff; 1140 mrx->m_pkthdr.len = mrx->m_len; 1141 mrx->m_pkthdr.rcvif = ifp; 1142 1143 ifp->if_ipackets++; 1144 ifp->if_input(ifp, mrx); 1145 rx_npkts++; --- 166 unchanged lines hidden (view full) --- 1312 while (sc->tx_free != NULL) { 1313 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1314 if (m == NULL) { 1315 /* XXX? */ 1316 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1317 return; 1318 } 1319 npe = sc->tx_free; |
1320 bus_dmamap_unload(dma->mtag, npe->ix_map); |
|
1317 error = bus_dmamap_load_mbuf_sg(dma->mtag, npe->ix_map, 1318 m, segs, &nseg, 0); 1319 if (error == EFBIG) { 1320 n = m_collapse(m, M_NOWAIT, NPE_MAXSEG); 1321 if (n == NULL) { 1322 if_printf(ifp, "%s: too many fragments %u\n", 1323 __func__, nseg); 1324 m_freem(m); --- 26 unchanged lines hidden (view full) --- 1351 hw->ix_ne[i].data = htobe32(segs[i].ds_addr); 1352 hw->ix_ne[i].len = htobe32((segs[i].ds_len<<16) | len); 1353 hw->ix_ne[i].next = htobe32(next); 1354 1355 len = 0; /* zero for segments > 1 */ 1356 next += sizeof(hw->ix_ne[0]); 1357 } 1358 hw->ix_ne[i-1].next = 0; /* zero last in chain */ | 1321 error = bus_dmamap_load_mbuf_sg(dma->mtag, npe->ix_map, 1322 m, segs, &nseg, 0); 1323 if (error == EFBIG) { 1324 n = m_collapse(m, M_NOWAIT, NPE_MAXSEG); 1325 if (n == NULL) { 1326 if_printf(ifp, "%s: too many fragments %u\n", 1327 __func__, nseg); 1328 m_freem(m); --- 26 unchanged lines hidden (view full) --- 1355 hw->ix_ne[i].data = htobe32(segs[i].ds_addr); 1356 hw->ix_ne[i].len = htobe32((segs[i].ds_len<<16) | len); 1357 hw->ix_ne[i].next = htobe32(next); 1358 1359 len = 0; /* zero for segments > 1 */ 1360 next += sizeof(hw->ix_ne[0]); 1361 } 1362 hw->ix_ne[i-1].next = 0; /* zero last in chain */ |
1359 /* XXX flush descriptor instead of using uncached memory */ | 1363 bus_dmamap_sync(dma->buf_tag, dma->buf_map, 1364 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); |
1360 1361 DPRINTF(sc, "%s: qwrite(%u, 0x%x) ne_data %x ne_len 0x%x\n", 1362 __func__, sc->tx_qid, npe->ix_neaddr, 1363 hw->ix_ne[0].data, hw->ix_ne[0].len); 1364 /* stick it on the tx q */ 1365 /* XXX add vlan priority */ 1366 ixpqmgr_qwrite(sc->tx_qid, npe->ix_neaddr); 1367 --- 411 unchanged lines hidden --- | 1365 1366 DPRINTF(sc, "%s: qwrite(%u, 0x%x) ne_data %x ne_len 0x%x\n", 1367 __func__, sc->tx_qid, npe->ix_neaddr, 1368 hw->ix_ne[0].data, hw->ix_ne[0].len); 1369 /* stick it on the tx q */ 1370 /* XXX add vlan priority */ 1371 ixpqmgr_qwrite(sc->tx_qid, npe->ix_neaddr); 1372 --- 411 unchanged lines hidden --- |