The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/hfa/fore_transmit.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * ===================================
    3  * HARP  |  Host ATM Research Platform
    4  * ===================================
    5  *
    6  * This Host ATM Research Platform ("HARP") file (the "Software") is
    7  * made available by Network Computing Services, Inc. ("NetworkCS")
    8  * "AS IS".  NetworkCS does not provide maintenance, improvements or
    9  * support of any kind.
   10  *
   11  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
   12  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
   13  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
   14  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
   15  * In no event shall NetworkCS be responsible for any damages, including
   16  * but not limited to consequential damages, arising from or relating to
   17  * any use of the Software or related support.
   18  *
   19  * Copyright 1994-1998 Network Computing Services, Inc.
   20  *
   21  * Copies of this Software may be made, however, the above copyright
   22  * notice must be reproduced on all copies.
   23  */
   24 
   25 #include <sys/cdefs.h>
   26 __FBSDID("$FreeBSD: releng/5.3/sys/dev/hfa/fore_transmit.c 126122 2004-02-22 16:27:28Z mux $");
   27 
   28 /*
   29  * FORE Systems 200-Series Adapter Support
   30  * ---------------------------------------
   31  *
   32  * Transmit queue management
   33  *
   34  */
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/socket.h>
   39 #include <sys/socketvar.h>
   40 #include <vm/vm.h>
   41 #include <vm/pmap.h>
   42 #include <net/if.h>
   43 #include <netatm/port.h>
   44 #include <netatm/queue.h>
   45 #include <netatm/atm.h>
   46 #include <netatm/atm_sys.h>
   47 #include <netatm/atm_sap.h>
   48 #include <netatm/atm_cm.h>
   49 #include <netatm/atm_if.h>
   50 #include <netatm/atm_vc.h>
   51 #include <netatm/atm_stack.h>
   52 #include <netatm/atm_pcb.h>
   53 #include <netatm/atm_var.h>
   54 #include <dev/pci/pcivar.h>
   55 #include <dev/hfa/fore.h>
   56 #include <dev/hfa/fore_aali.h>
   57 #include <dev/hfa/fore_slave.h>
   58 #include <dev/hfa/fore_stats.h>
   59 #include <dev/hfa/fore_var.h>
   60 #include <dev/hfa/fore_include.h>
   61 
   62 #ifndef lint
   63 __RCSID("@(#) $FreeBSD: releng/5.3/sys/dev/hfa/fore_transmit.c 126122 2004-02-22 16:27:28Z mux $");
   64 #endif
   65 
   66 
   67 /*
   68  * Allocate Transmit Queue Data Structures
   69  *
   70  * Arguments:
   71  *      fup             pointer to device unit structure
   72  *
   73  * Returns:
   74  *      0               allocations successful
   75  *      else            allocation failed
   76  */
   77 int
   78 fore_xmit_allocate(fup)
   79         Fore_unit       *fup;
   80 {
   81         void            *memp;
   82         vm_paddr_t      pmemp;
   83         H_xmit_queue    *hxp;
   84         int             i;
   85 
   86         /*
   87          * Allocate non-cacheable memory for transmit status words
   88          */
   89         memp = atm_dev_alloc(sizeof(Q_status) * XMIT_QUELEN,
   90                         QSTAT_ALIGN, ATM_DEV_NONCACHE);
   91         if (memp == NULL) {
   92                 return (1);
   93         }
   94         fup->fu_xmit_stat = (Q_status *) memp;
   95 
   96         pmemp = vtophys(fup->fu_xmit_stat);
   97         if (pmemp == 0) {
   98                 return (1);
   99         }
  100         fup->fu_xmit_statd = pmemp;
  101 
  102         /*
  103          * Allocate memory for transmit descriptors
  104          *
  105          * We will allocate the transmit descriptors individually rather than 
  106          * as a single memory block, which will often be larger than a memory
  107          * page.  On some systems (eg. FreeBSD) the physical addresses of 
  108          * adjacent virtual memory pages are not contiguous.
  109          */
  110         hxp = fup->fu_xmit_q;
  111         for (i = 0; i < XMIT_QUELEN; i++, hxp++) {
  112 
  113                 /*
  114                  * Allocate a transmit descriptor for this queue entry
  115                  */
  116                 hxp->hxq_descr = atm_dev_alloc(sizeof(Xmit_descr),
  117                         XMIT_DESCR_ALIGN, 0);
  118                 if (hxp->hxq_descr == NULL) {
  119                         return (1);
  120                 }
  121 
  122                 hxp->hxq_descr_dma = vtophys(hxp->hxq_descr);
  123                 if (hxp->hxq_descr_dma == 0) {
  124                         return (1);
  125                 }
  126         }
  127 
  128         return (0);
  129 }
  130 
  131 
  132 /*
  133  * Transmit Queue Initialization
  134  *
  135  * Allocate and initialize the host-resident transmit queue structures
  136  * and then initialize the CP-resident queue structures.
  137  * 
  138  * Called at interrupt level.
  139  *
  140  * Arguments:
  141  *      fup             pointer to device unit structure
  142  *
  143  * Returns:
  144  *      none
  145  */
  146 void
  147 fore_xmit_initialize(fup)
  148         Fore_unit       *fup;
  149 {
  150         Aali            *aap = fup->fu_aali;
  151         Xmit_queue      *cqp;
  152         H_xmit_queue    *hxp;
  153         Q_status        *qsp;
  154         vm_paddr_t      qsp_dma;
  155         int             i;
  156 
  157         /*
  158          * Point to CP-resident transmit queue
  159          */
  160         cqp = (Xmit_queue *)(fup->fu_ram + CP_READ(aap->aali_xmit_q));
  161 
  162         /*
  163          * Point to host-resident transmit queue structures
  164          */
  165         hxp = fup->fu_xmit_q;
  166         qsp = fup->fu_xmit_stat;
  167         qsp_dma = fup->fu_xmit_statd;
  168 
  169         /*
  170          * Loop thru all queue entries and do whatever needs doing
  171          */
  172         for (i = 0; i < XMIT_QUELEN; i++) {
  173 
  174                 /*
  175                  * Set queue status word to free
  176                  */
  177                 *qsp = QSTAT_FREE;
  178 
  179                 /*
  180                  * Set up host queue entry and link into ring
  181                  */
  182                 hxp->hxq_cpelem = cqp;
  183                 hxp->hxq_status = qsp;
  184                 if (i == (XMIT_QUELEN - 1))
  185                         hxp->hxq_next = fup->fu_xmit_q;
  186                 else
  187                         hxp->hxq_next = hxp + 1;
  188 
  189                 /*
  190                  * Now let the CP into the game
  191                  */
  192                 cqp->cq_status = (CP_dma) CP_WRITE(qsp_dma);
  193 
  194                 /*
  195                  * Bump all queue pointers
  196                  */
  197                 hxp++;
  198                 qsp++;
  199                 qsp_dma += sizeof(Q_status);
  200                 cqp++;
  201         }
  202 
  203         /*
  204          * Initialize queue pointers
  205          */
  206         fup->fu_xmit_head = fup->fu_xmit_tail = fup->fu_xmit_q;
  207 
  208         return;
  209 }
  210 
  211 
  212 /*
  213  * Drain Transmit Queue
  214  *
  215  * This function will free all completed entries at the head of the
  216  * transmit queue.  Freeing the entry includes releasing the transmit
  217  * buffers (buffer chain) back to the kernel.  
  218  *
  219  * May be called in interrupt state.
  220  * Must be called with interrupts locked out.
  221  *
  222  * Arguments:
  223  *      fup             pointer to device unit structure
  224  *
  225  * Returns:
  226  *      none
  227  */
  228 void
  229 fore_xmit_drain(fup)
  230         Fore_unit       *fup;
  231 {
  232         H_xmit_queue    *hxp;
  233         H_dma           *sdmap;
  234         Fore_vcc        *fvp;
  235         struct vccb     *vcp;
  236         KBuffer         *m;
  237 
  238         /*
  239          * Process each completed entry
  240          */
  241         while (*fup->fu_xmit_head->hxq_status & QSTAT_COMPLETED) {
  242 
  243                 hxp = fup->fu_xmit_head;
  244 
  245                 /*
  246                  * Release the entry's DMA addresses and buffer chain
  247                  */
  248                 for (m = hxp->hxq_buf, sdmap = hxp->hxq_dma; m;
  249                                 m = KB_NEXT(m), sdmap++) {
  250                         caddr_t         cp;
  251 
  252                         KB_DATASTART(m, cp, caddr_t);
  253                 }
  254                 KB_FREEALL(hxp->hxq_buf);
  255 
  256                 /*
  257                  * Get VCC over which data was sent (may be null if
  258                  * VCC has been closed in the meantime)
  259                  */
  260                 fvp = hxp->hxq_vcc;
  261 
  262                 /*
  263                  * Now collect some statistics
  264                  */
  265                 if (*hxp->hxq_status & QSTAT_ERROR) {
  266                         /*
  267                          * CP ran into problems, not much we can do
  268                          * other than record the event
  269                          */
  270                         fup->fu_pif.pif_oerrors++;
  271                         if (fvp) {
  272                                 vcp = fvp->fv_connvc->cvc_vcc;
  273                                 vcp->vc_oerrors++;
  274                                 if (vcp->vc_nif)
  275                                         vcp->vc_nif->nif_if.if_oerrors++;
  276                         }
  277                 } else {
  278                         /*
  279                          * Good transmission
  280                          */
  281                         int     len = XDS_GET_LEN(hxp->hxq_descr->xd_spec);
  282 
  283                         fup->fu_pif.pif_opdus++;
  284                         fup->fu_pif.pif_obytes += len;
  285                         if (fvp) {
  286                                 vcp = fvp->fv_connvc->cvc_vcc;
  287                                 vcp->vc_opdus++;
  288                                 vcp->vc_obytes += len;
  289                                 if (vcp->vc_nif) {
  290                                         vcp->vc_nif->nif_obytes += len;
  291                                         vcp->vc_nif->nif_if.if_opackets++;
  292 #if (defined(BSD) && (BSD >= 199103))
  293                                         vcp->vc_nif->nif_if.if_obytes += len;
  294 #endif
  295                                 }
  296                         }
  297                 }
  298 
  299                 /*
  300                  * Mark this entry free for use and bump head pointer
  301                  * to the next entry in the queue
  302                  */
  303                 *hxp->hxq_status = QSTAT_FREE;
  304                 fup->fu_xmit_head = hxp->hxq_next;
  305         }
  306 
  307         return;
  308 }
  309 
  310 
  311 /*
  312  * Free Transmit Queue Data Structures
  313  *
  314  * Arguments:
  315  *      fup             pointer to device unit structure
  316  *
  317  * Returns:
  318  *      none
  319  */
  320 void
  321 fore_xmit_free(fup)
  322         Fore_unit       *fup;
  323 {
  324         H_xmit_queue    *hxp;
  325         H_dma           *sdmap;
  326         KBuffer         *m;
  327         int             i;
  328 
  329         /*
  330          * Free any transmit buffers left on the queue
  331          */
  332         if (fup->fu_flags & CUF_INITED) {
  333                 while (*fup->fu_xmit_head->hxq_status != QSTAT_FREE) {
  334 
  335                         hxp = fup->fu_xmit_head;
  336 
  337                         /*
  338                          * Release the entry's DMA addresses and buffer chain
  339                          */
  340                         for (m = hxp->hxq_buf, sdmap = hxp->hxq_dma; m;
  341                                         m = KB_NEXT(m), sdmap++) {
  342                                 caddr_t         cp;
  343 
  344                                 KB_DATASTART(m, cp, caddr_t);
  345                         }
  346                         KB_FREEALL(hxp->hxq_buf);
  347 
  348                         *hxp->hxq_status = QSTAT_FREE;
  349                         fup->fu_xmit_head = hxp->hxq_next;
  350                 }
  351         }
  352 
  353         /*
  354          * Free the status words
  355          */
  356         if (fup->fu_xmit_stat) {
  357                 atm_dev_free((volatile void *)fup->fu_xmit_stat);
  358                 fup->fu_xmit_stat = NULL;
  359                 fup->fu_xmit_statd = 0;
  360         }
  361 
  362         /*
  363          * Free the transmit descriptors
  364          */
  365         hxp = fup->fu_xmit_q;
  366         for (i = 0; i < XMIT_QUELEN; i++, hxp++) {
  367 
  368                 /*
  369                  * Free the transmit descriptor for this queue entry
  370                  */
  371                 if (hxp->hxq_descr_dma) {
  372                         hxp->hxq_descr_dma = 0;
  373                 }
  374 
  375                 if (hxp->hxq_descr) {
  376                         atm_dev_free(hxp->hxq_descr);
  377                         hxp->hxq_descr = NULL;
  378                 }
  379         }
  380 
  381         return;
  382 }
  383 

Cache object: e5e796106857073b91c90f0b2018d713


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.