summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_san_common.c99
-rw-r--r--sys/dev/pci/if_san_xilinx.c75
2 files changed, 77 insertions, 97 deletions
diff --git a/sys/dev/pci/if_san_common.c b/sys/dev/pci/if_san_common.c
index e641dc05bd1..dbbff25a4a4 100644
--- a/sys/dev/pci/if_san_common.c
+++ b/sys/dev/pci/if_san_common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_san_common.c,v 1.8 2005/04/05 20:11:10 canacar Exp $ */
+/* $OpenBSD: if_san_common.c,v 1.9 2005/09/01 23:35:42 canacar Exp $ */
/*-
* Copyright (c) 2001-2004 Sangoma Technologies (SAN)
@@ -383,56 +383,91 @@ sdla_isr(void *pcard)
return (1);
}
-// XXX check usage, why is len not used ???
struct mbuf*
wan_mbuf_alloc(int len)
{
struct mbuf *m;
- if (len)
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- else
- MGET(m, M_DONTWAIT, MT_DATA);
+ /* XXX handle len > MCLBYTES */
+ if (len <= 0 || len > MCLBYTES)
+ return (NULL);
- if (m != NULL) {
- if (m->m_flags & M_PKTHDR)
- m->m_pkthdr.len = 0;
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
- m->m_len = 0;
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0) {
- m_freem(m);
- return NULL;
- }
+ if (m == NULL || len < MHLEN)
+ return (m);
- m->m_data += 16;
+ m->m_pkthdr.len = 0;
+ m->m_len = 0;
+ MCLGET(m, M_DONTWAIT);
+
+ if ((m->m_flags & M_EXT) == 0) {
+ m_freem(m);
+ return (NULL);
}
+
return (m);
}
-// XXX check len while copy?
int
wan_mbuf_to_buffer(struct mbuf **m_org)
{
- struct mbuf *m = *m_org, *new = NULL;
+ struct mbuf *m, *m0, *tmp;
+ char *buffer;
+ size_t len;
+
+ if (m_org == NULL || *m_org == NULL)
+ return (EINVAL);
+
+ m0 = *m_org;
+#if 0
+ /* no need to copy if it is a single, properly aligned mbuf */
+ if (m0->m_next == NULL && (mtod(m0, u_int32_t) & 0x03) == 0)
+ return (0);
+#endif
+ MGET(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
- return EINVAL;
+ return (ENOMEM);
- new = wan_mbuf_alloc(0);
- if (new){
- struct mbuf *tmp = m;
- char *buffer = new->m_data;
+ MCLGET(m, M_DONTWAIT);
- for( ; tmp; tmp = tmp->m_next) {
- bcopy(mtod(tmp, caddr_t), buffer, tmp->m_len);
- buffer += tmp->m_len;
- new->m_len += tmp->m_len;
- }
+ if ((m->m_flags & M_EXT) == 0) {
m_freem(m);
- *m_org = new;
- return 0;
+ return (ENOMEM);
}
- return EINVAL;
-}
+ m->m_len = 0;
+
+ /* XXX handle larger packets? */
+ len = MCLBYTES ;
+ buffer = mtod(m, caddr_t);
+
+ len -= 16;
+ buffer += 16;
+
+ /* make sure the buffer is aligned to an 8-byte boundary */
+ if (mtod(m, u_int32_t) & 0x03) {
+ unsigned int inc = 4 - (mtod(m, u_int32_t) & 0x03);
+ buffer += inc;
+ len -= inc;
+ }
+
+ m->m_data = buffer;
+
+ for (tmp = m0; tmp; tmp = tmp->m_next) {
+ if (tmp->m_len > len) {
+ m_freem(m);
+ return (EINVAL);
+ }
+ bcopy(mtod(tmp, caddr_t), buffer, tmp->m_len);
+ buffer += tmp->m_len;
+ m->m_len += tmp->m_len;
+ len -= tmp->m_len;
+ }
+
+ m_freem(m0);
+ *m_org = m;
+
+ return (0);
+}
diff --git a/sys/dev/pci/if_san_xilinx.c b/sys/dev/pci/if_san_xilinx.c
index b8a3795fb51..3a821291acd 100644
--- a/sys/dev/pci/if_san_xilinx.c
+++ b/sys/dev/pci/if_san_xilinx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_san_xilinx.c,v 1.10 2005/04/25 17:55:51 brad Exp $ */
+/* $OpenBSD: if_san_xilinx.c,v 1.11 2005/09/01 23:35:42 canacar Exp $ */
/*-
* Copyright (c) 2001-2004 Sangoma Technologies (SAN)
@@ -164,11 +164,6 @@ typedef struct {
void *prot_ch;
wan_trace_t trace_info;
-
- u_int8_t tx_dma_status;
- bus_dma_segment_t tx_dma_seg;
- int tx_dma_rseg;
- caddr_t tx_dma_vaddr;
}xilinx_softc_t;
#define WAN_IFP_TO_SOFTC(ifp) (xilinx_softc_t *)((ifp)->if_softc)
@@ -572,14 +567,6 @@ wan_xilinx_down(struct ifnet *ifp)
aft_init_requeue_free_m(sc, m);
sc->rx_dma_mbuf = NULL;
}
- if (bit_test((u_int8_t *)&sc->tx_dma_status, TX_DMA_BUF_INIT)){
- bus_dma_tag_t dmat;
-
- sdla_getcfg(card->hw, SDLA_DMATAG, &dmat);
- bus_dmamem_unmap(dmat, sc->tx_dma_vaddr, sc->dma_mtu);
- bus_dmamem_free(dmat, &sc->tx_dma_seg, sc->tx_dma_rseg);
- bit_clear((u_int8_t *)&sc->tx_dma_status, TX_DMA_BUF_INIT);
- }
/* If there is something in rx_complete_list, then
** move evething to rx_free_list. */
@@ -1852,58 +1839,16 @@ xilinx_dma_tx(sdla_t *card, xilinx_softc_t *sc)
}
if (mtod(m, u_int32_t) & 0x03) {
- if (!bit_test((u_int8_t *)&sc->tx_dma_status,
- TX_DMA_BUF_INIT)) {
- bus_dma_tag_t dmat;
- int err;
-
- sdla_getcfg(card->hw, SDLA_DMATAG, &dmat);
- err = bus_dmamem_alloc(
- dmat,
- sc->dma_mtu,
- PAGE_SIZE,
- 0,
- &sc->tx_dma_seg,
- 1,
- &sc->tx_dma_rseg,
- BUS_DMA_NOWAIT);
- if (err) {
- log(LOG_INFO,
- "%s: Failed allocate DMA buffer!\n",
- sc->if_name);
- m_freem(m);
- bit_clear((u_int8_t *)&sc->dma_status,
- TX_BUSY);
- return (EINVAL);
- }
- err = bus_dmamem_map(
- dmat,
- &sc->tx_dma_seg,
- sc->tx_dma_rseg,
- sc->dma_mtu,
- (caddr_t*)&sc->tx_dma_vaddr,
- BUS_DMA_NOWAIT);
- if (err) {
- log(LOG_INFO,
- "%s: Failed to map DMA buffer!\n",
- sc->if_name);
- bus_dmamem_free(
- dmat,
- &sc->tx_dma_seg,
- sc->tx_dma_rseg);
- m_freem(m);
- bit_clear((u_int8_t *)&sc->dma_status,
- TX_BUSY);
- return (EINVAL);
- }
- bit_set((u_int8_t *)&sc->tx_dma_status,
- TX_DMA_BUF_INIT);
- }
- memcpy(sc->tx_dma_vaddr, mtod(m, caddr_t), m->m_len);
- sc->tx_dma_addr = kvtop(sc->tx_dma_vaddr);
- } else {
- sc->tx_dma_addr = kvtop(mtod(m, caddr_t));
+ /* The mbuf should already be aligned */
+ log(LOG_INFO, "%s: TX packed not aligned "
+ "(%s:%d)!\n", sc->if_name,
+ MAX_XILINX_TX_DMA_SIZE, __FUNCTION__, __LINE__);
+ m_freem(m);
+ bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
+ return (EINVAL);
}
+
+ sc->tx_dma_addr = kvtop(mtod(m, caddr_t));
sc->tx_dma_len = len;
}