Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/mips/sibyte/dev initial support for mac features in...



details:   https://anonhg.NetBSD.org/src/rev/0a7d4243e4c6
branches:  trunk
changeset: 539495:0a7d4243e4c6
user:      cgd <cgd%NetBSD.org@localhost>
date:      Tue Nov 19 01:44:04 2002 +0000

description:
initial support for mac features in new chip revs

diffstat:

 sys/arch/mips/sibyte/dev/sbmac.c |  260 ++++++++++++++++++++++++++++----------
 1 files changed, 188 insertions(+), 72 deletions(-)

diffs (truncated from 344 to 300 lines):

diff -r 324332e0ceb7 -r 0a7d4243e4c6 sys/arch/mips/sibyte/dev/sbmac.c
--- a/sys/arch/mips/sibyte/dev/sbmac.c  Mon Nov 18 23:50:47 2002 +0000
+++ b/sys/arch/mips/sibyte/dev/sbmac.c  Tue Nov 19 01:44:04 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sbmac.c,v 1.7 2002/11/08 19:40:05 cgd Exp $ */
+/* $NetBSD: sbmac.c,v 1.8 2002/11/19 01:44:04 cgd Exp $ */
 
 /*
  * Copyright 2000, 2001
@@ -79,6 +79,7 @@
 #include <mips/sibyte/include/sb1250_regs.h>
 #include <mips/sibyte/include/sb1250_mac.h>
 #include <mips/sibyte/include/sb1250_dma.h>
+#include <mips/sibyte/include/sb1250_scd.h>
 
 
 /* Simple types */
@@ -208,6 +209,8 @@
 
        sbmacdma_t      sbm_txdma;      /* for now, only use channel 0 */
        sbmacdma_t      sbm_rxdma;
+
+       int             sbm_pass3_dma;  /* chip has pass3 SOC DMA features */
 };
 
 
@@ -571,8 +574,11 @@
 {
        sbdmadscr_t *dsc;
        sbdmadscr_t *nextdsc;
-       struct mbuf *m_new = NULL;
+       sbdmadscr_t *prevdsc;
+       sbdmadscr_t *origdesc;
        int length;
+       int num_mbufs = 0;
+       struct sbmac_softc *sc = d->sbdma_eth;
 
        /* get pointer to our current place in the ring */
 
@@ -603,80 +609,150 @@
 #endif
 
        /*
-        * [BEGIN XXX]
-        * XXX Copy/coalesce the mbufs into a single mbuf cluster (we assume
-        * it will fit).  This is a temporary hack to get us going.
-        */
-
-       MGETHDR(m_new, M_DONTWAIT, MT_DATA);
-       if (m_new == NULL) {
-               printf("%s: mbuf allocation failed\n",
-               d->sbdma_eth->sc_dev.dv_xname);
-               return ENOBUFS;
-       }
-
-       MCLGET(m_new, M_DONTWAIT);
-       if (!(m_new->m_flags & M_EXT)) {
-               printf("%s: mbuf cluster allocation failed\n",
-               d->sbdma_eth->sc_dev.dv_xname);
-               m_freem(m_new);
-               return ENOBUFS;
-       }
-
-       m_new->m_len = m_new->m_pkthdr.len= MCLBYTES;
-       /*m_adj(m_new, ETHER_ALIGN);*/
-
-       /*
-        * XXX Don't forget to include the offset portion in the
-        * XXX cache block calculation when this code is rewritten!
-        */
-
-       /*
-        * Copy data
+        * PASS3 parts do not have buffer alignment restriction.
+        * No need to copy/coalesce to new mbuf.  Also has different
+        * descriptor format
         */
-
-       m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t));
-       m_new->m_len = m_new->m_pkthdr.len = m->m_pkthdr.len;
-
-       /* Free old mbuf 'm', actual mbuf is now 'm_new' */
-
-       // XXX: CALLERS WILL FREE, they might have to bpf_mtap() if this
-       // XXX: function succeeds.
-       // m_freem(m);
-       length = m_new->m_len;
-
-       /* [END XXX] */
-
-       /*
-        * fill in the descriptor
-        */
-
-       dsc->dscr_a = KVTOPHYS(mtod(m_new, caddr_t)) |
-           V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(m_new->m_len)) |
-           M_DMA_DSCRA_INTERRUPT |
-           M_DMA_ETHTX_SOP;
-
-       /* transmitting: set outbound options and length */
-       dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
-           V_DMA_DSCRB_PKT_SIZE(length);
-
-       /*
-        * fill in the context
-        */
-
-       d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = m_new;
-
-       /*
-        * point at next packet
-        */
-
-       d->sbdma_addptr = nextdsc;
+       if (sc->sbm_pass3_dma) {
+               struct mbuf *m_temp = NULL;
+
+               /*
+                * Loop thru this mbuf record.
+                * The head mbuf will have SOP set.
+                */
+               dsc->dscr_a = KVTOPHYS(mtod(m,caddr_t)) |
+                   M_DMA_DSCRA_INTERRUPT |
+                   M_DMA_ETHTX_SOP;
+
+               /*
+                * transmitting: set outbound options,buffer A size(+ low 5
+                * bits of start addr),and packet length.
+                */
+               dsc->dscr_b =
+                   V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
+                   V_DMA_DSCRB_A_SIZE((m->m_len + (mtod(m,unsigned int) & 0x0000001F))) |
+                   V_DMA_DSCRB_PKT_SIZE_MSB( (m->m_pkthdr.len & 0xB000) ) |
+                   V_DMA_DSCRB_PKT_SIZE(m->m_pkthdr.len);
+
+               d->sbdma_addptr = nextdsc;
+               origdesc = prevdsc = dsc;
+               dsc = d->sbdma_addptr;
+               num_mbufs++;
+
+               /* Start with first non-head mbuf */
+               for(m_temp = m->m_next; m_temp != 0; m_temp = m_temp->m_next) {
+
+                       if (m_temp->m_len == 0)
+                               continue;       /* Skip 0-length mbufs */
+
+                       /*
+                        * fill in the descriptor
+                        */
+
+                       dsc->dscr_a = KVTOPHYS(mtod(m_temp,caddr_t)) |
+                           M_DMA_DSCRA_INTERRUPT;
+
+                       /* transmitting: set outbound options,buffer A size(+ low 5 bits of start addr) */
+                       dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_NOTSOP) |
+                           V_DMA_DSCRB_A_SIZE( (m_temp->m_len + (mtod(m_temp,unsigned int) & 0x0000001F)) );
+
+                       d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = NULL;
+
+                       /*
+                        * point at next descriptor
+                        */
+                       nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr);
+                       if (nextdsc == d->sbdma_remptr) {
+                               d->sbdma_addptr = origdesc;
+                               return ENOSPC;
+                       }
+                       d->sbdma_addptr = nextdsc;
+
+                       prevdsc = dsc;
+                       dsc = d->sbdma_addptr;
+                       num_mbufs++;
+               }
+
+               /*Set head mbuf to last context index*/
+               d->sbdma_ctxtable[prevdsc-d->sbdma_dscrtable] = m;
+       } else {
+               struct mbuf *m_new = NULL;
+               /*
+                * [BEGIN XXX]
+                * XXX Copy/coalesce the mbufs into a single mbuf cluster (we assume
+                * it will fit).  This is a temporary hack to get us going.
+                */
+
+               MGETHDR(m_new,M_DONTWAIT,MT_DATA);
+               if (m_new == NULL) {
+                       printf("%s: mbuf allocation failed\n",
+                           d->sbdma_eth->sc_dev.dv_xname);
+                       return ENOBUFS;
+               }
+
+               MCLGET(m_new,M_DONTWAIT);
+               if (!(m_new->m_flags & M_EXT)) {
+                       printf("%s: mbuf cluster allocation failed\n",
+                           d->sbdma_eth->sc_dev.dv_xname);
+                       m_freem(m_new);
+                       return ENOBUFS;
+               }
+
+               m_new->m_len = m_new->m_pkthdr.len= MCLBYTES;
+               /*m_adj(m_new,ETHER_ALIGN);*/
+
+               /*
+                * XXX Don't forget to include the offset portion in the
+                * XXX cache block calculation when this code is rewritten!
+                */
+
+               /*
+                * Copy data
+                */
+
+               m_copydata(m,0,m->m_pkthdr.len,mtod(m_new,caddr_t));
+               m_new->m_len = m_new->m_pkthdr.len = m->m_pkthdr.len;
+
+               /* Free old mbuf 'm', actual mbuf is now 'm_new' */
+
+               // XXX: CALLERS WILL FREE, they might have to bpf_mtap() if this
+               // XXX: function succeeds.
+               // m_freem(m);
+               length = m_new->m_len;
+
+               /* [END XXX] */
+               /*
+                * fill in the descriptor
+                */
+
+               dsc->dscr_a = KVTOPHYS(mtod(m_new,caddr_t)) |
+                   V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(m_new->m_len)) |
+                   M_DMA_DSCRA_INTERRUPT |
+                   M_DMA_ETHTX_SOP;
+
+               /* transmitting: set outbound options and length */
+               dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
+                   V_DMA_DSCRB_PKT_SIZE(length);
+
+               num_mbufs++;
+
+               /*
+                * fill in the context
+                */
+
+               d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = m_new;
+
+               /*
+                * point at next packet
+                */
+               d->sbdma_addptr = nextdsc;
+       }
 
        /*
         * Give the buffer to the DMA engine.
         */
 
-       SBMAC_WRITECSR(d->sbdma_dscrcnt, 1);
+       SBMAC_WRITECSR(d->sbdma_dscrcnt, num_mbufs);
 
        return 0;                                       /* we did it */
 }
@@ -952,6 +1028,7 @@
 static void
 sbmac_initctx(struct sbmac_softc *s)
 {
+       uint64_t sysrev;
 
        /*
         * figure out the addresses of some ports
@@ -986,6 +1063,16 @@
        s->sbm_speed = sbmac_speed_10;
        s->sbm_duplex = sbmac_duplex_half;
        s->sbm_fc = sbmac_fc_disabled;
+
+       /* 
+        * Determine SOC type.  112x has Pass3 SOC features.
+        */
+       sysrev = SBMAC_READCSR( PKSEG1(A_SCD_SYSTEM_REVISION) );
+       s->sbm_pass3_dma = (SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1120 ||
+                           SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1125 ||
+                           SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1125H ||
+                           (SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250 &&
+                            0));
 }
 
 /*
@@ -1007,6 +1094,8 @@
        sbmac_port_t port;
        uint64_t cfg, fifo, framecfg;
        int idx;
+       uint64_t dma_cfg0, fifo_cfg;
+       sbmacdma_t *txdma;
 
        /*
         * Don't do this if running
@@ -1152,6 +1241,25 @@
        SBMAC_WRITECSR(s->sbm_rxfilter, M_MAC_UCAST_EN | M_MAC_BCAST_EN);
 
        /*
+        * On chips which support unaligned DMA features, set the descriptor
+        * ring for transmit channels to use the unaligned buffer format.
+        */
+       txdma = &(s->sbm_txdma); 



Home | Main Index | Thread Index | Old Index