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/mips/cavium/octe/ethernet.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 SPDX-License-Identifier: BSD-3-Clause
    3 
    4 Copyright (c) 2003-2007  Cavium Networks (support@cavium.com). All rights
    5 reserved.
    6 
    7 
    8 Redistribution and use in source and binary forms, with or without
    9 modification, are permitted provided that the following conditions are
   10 met:
   11 
   12     * Redistributions of source code must retain the above copyright
   13       notice, this list of conditions and the following disclaimer.
   14 
   15     * Redistributions in binary form must reproduce the above
   16       copyright notice, this list of conditions and the following
   17       disclaimer in the documentation and/or other materials provided
   18       with the distribution.
   19 
   20     * Neither the name of Cavium Networks nor the names of
   21       its contributors may be used to endorse or promote products
   22       derived from this software without specific prior written
   23       permission.
   24 
   25 This Software, including technical data, may be subject to U.S. export  control laws, including the U.S. Export Administration Act and its  associated regulations, and may be subject to export or import  regulations in other countries.
   26 
   27 TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
   28 AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
   29 *************************************************************************/
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/bus.h>
   37 #include <sys/conf.h>
   38 #include <sys/endian.h>
   39 #include <sys/kernel.h>
   40 #include <sys/rman.h>
   41 #include <sys/mbuf.h>
   42 #include <sys/socket.h>
   43 #include <sys/module.h>
   44 #include <sys/smp.h>
   45 #include <sys/taskqueue.h>
   46 
   47 #include <net/ethernet.h>
   48 #include <net/if.h>
   49 #include <net/if_var.h>
   50 #include <net/if_types.h>
   51 
   52 #include "wrapper-cvmx-includes.h"
   53 #include "ethernet-headers.h"
   54 
   55 #include "octebusvar.h"
   56 
   57 /*
   58  * XXX/juli
   59  * Convert 0444 to tunables, 0644 to sysctls.
   60  */
   61 #if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) && CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
   62 int num_packet_buffers = CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS;
   63 #else
   64 int num_packet_buffers = 2048;
   65 #endif
   66 TUNABLE_INT("hw.octe.num_packet_buffers", &num_packet_buffers);
   67 /*
   68                  "\t\tNumber of packet buffers to allocate and store in the\n"
   69                  "\t\tFPA. By default, 1024 packet buffers are used unless\n"
   70                  "\t\tCONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS is defined." */
   71 
   72 int pow_receive_group = 15;
   73 TUNABLE_INT("hw.octe.pow_receive_group", &pow_receive_group);
   74 /*
   75                  "\t\tPOW group to receive packets from. All ethernet hardware\n"
   76                  "\t\twill be configured to send incomming packets to this POW\n"
   77                  "\t\tgroup. Also any other software can submit packets to this\n"
   78                  "\t\tgroup for the kernel to process." */
   79 
   80 /**
   81  * Periodic timer to check auto negotiation
   82  */
   83 static struct callout cvm_oct_poll_timer;
   84 
   85 /**
   86  * Array of every ethernet device owned by this driver indexed by
   87  * the ipd input port number.
   88  */
   89 struct ifnet *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
   90 
   91 /**
   92  * Task to handle link status changes.
   93  */
   94 static struct taskqueue *cvm_oct_link_taskq;
   95 
   96 /*
   97  * Number of buffers in output buffer pool.
   98  */
   99 static int cvm_oct_num_output_buffers;
  100 
  101 /**
  102  * Function to update link status.
  103  */
  104 static void cvm_oct_update_link(void *context, int pending)
  105 {
  106         cvm_oct_private_t *priv = (cvm_oct_private_t *)context;
  107         struct ifnet *ifp = priv->ifp;
  108         cvmx_helper_link_info_t link_info;
  109 
  110         link_info.u64 = priv->link_info;
  111 
  112         if (link_info.s.link_up) {
  113                 if_link_state_change(ifp, LINK_STATE_UP);
  114                 DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
  115                            if_name(ifp), link_info.s.speed,
  116                            (link_info.s.full_duplex) ? "Full" : "Half",
  117                            priv->port, priv->queue);
  118         } else {
  119                 if_link_state_change(ifp, LINK_STATE_DOWN);
  120                 DEBUGPRINT("%s: Link down\n", if_name(ifp));
  121         }
  122         priv->need_link_update = 0;
  123 }
  124 
  125 /**
  126  * Periodic timer tick for slow management operations
  127  *
  128  * @param arg    Device to check
  129  */
  130 static void cvm_do_timer(void *arg)
  131 {
  132         static int port;
  133         static int updated;
  134         if (port < CVMX_PIP_NUM_INPUT_PORTS) {
  135                 if (cvm_oct_device[port]) {
  136                         int queues_per_port;
  137                         int qos;
  138                         cvm_oct_private_t *priv = (cvm_oct_private_t *)cvm_oct_device[port]->if_softc;
  139 
  140                         cvm_oct_common_poll(priv->ifp);
  141                         if (priv->need_link_update) {
  142                                 updated++;
  143                                 taskqueue_enqueue(cvm_oct_link_taskq, &priv->link_task);
  144                         }
  145 
  146                         queues_per_port = cvmx_pko_get_num_queues(port);
  147                         /* Drain any pending packets in the free list */
  148                         for (qos = 0; qos < queues_per_port; qos++) {
  149                                 if (_IF_QLEN(&priv->tx_free_queue[qos]) > 0) {
  150                                         IF_LOCK(&priv->tx_free_queue[qos]);
  151                                         while (_IF_QLEN(&priv->tx_free_queue[qos]) > cvmx_fau_fetch_and_add32(priv->fau+qos*4, 0)) {
  152                                                 struct mbuf *m;
  153 
  154                                                 _IF_DEQUEUE(&priv->tx_free_queue[qos], m);
  155                                                 m_freem(m);
  156                                         }
  157                                         IF_UNLOCK(&priv->tx_free_queue[qos]);
  158 
  159                                         /*
  160                                          * XXX locking!
  161                                          */
  162                                         priv->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  163                                 }
  164                         }
  165                 }
  166                 port++;
  167                 /* Poll the next port in a 50th of a second.
  168                    This spreads the polling of ports out a little bit */
  169                 callout_reset(&cvm_oct_poll_timer, hz / 50, cvm_do_timer, NULL);
  170         } else {
  171                 port = 0;
  172                 /* If any updates were made in this run, continue iterating at
  173                  * 1/50th of a second, so that if a link has merely gone down
  174                  * temporarily (e.g. because of interface reinitialization) it
  175                  * will not be forced to stay down for an entire second.
  176                  */
  177                 if (updated > 0) {
  178                         updated = 0;
  179                         callout_reset(&cvm_oct_poll_timer, hz / 50, cvm_do_timer, NULL);
  180                 } else {
  181                         /* All ports have been polled. Start the next iteration through
  182                            the ports in one second */
  183                         callout_reset(&cvm_oct_poll_timer, hz, cvm_do_timer, NULL);
  184                 }
  185         }
  186 }
  187 
  188 /**
  189  * Configure common hardware for all interfaces
  190  */
  191 static void cvm_oct_configure_common_hw(device_t bus)
  192 {
  193         struct octebus_softc *sc;
  194         int pko_queues;
  195         int error;
  196         int rid;
  197 
  198         sc = device_get_softc(bus);
  199 
  200         /* Setup the FPA */
  201         cvmx_fpa_enable();
  202         cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
  203                              num_packet_buffers);
  204         cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
  205                              num_packet_buffers);
  206         if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL) {
  207                 /*
  208                  * If the FPA uses different pools for output buffers and
  209                  * packets, size the output buffer pool based on the number
  210                  * of PKO queues.
  211                  */
  212                 if (OCTEON_IS_MODEL(OCTEON_CN38XX))
  213                         pko_queues = 128;
  214                 else if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
  215                         pko_queues = 32;
  216                 else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
  217                         pko_queues = 32;
  218                 else
  219                         pko_queues = 256;
  220 
  221                 cvm_oct_num_output_buffers = 4 * pko_queues;
  222                 cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
  223                                      CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE,
  224                                      cvm_oct_num_output_buffers);
  225         }
  226 
  227         if (USE_RED)
  228                 cvmx_helper_setup_red(num_packet_buffers/4,
  229                                       num_packet_buffers/8);
  230 
  231         /* Enable the MII interface */
  232         if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM)
  233                 cvmx_write_csr(CVMX_SMI_EN, 1);
  234 
  235         /* Register an IRQ hander for to receive POW interrupts */
  236         rid = 0;
  237         sc->sc_rx_irq = bus_alloc_resource(bus, SYS_RES_IRQ, &rid,
  238                                            OCTEON_IRQ_WORKQ0 + pow_receive_group,
  239                                            OCTEON_IRQ_WORKQ0 + pow_receive_group,
  240                                            1, RF_ACTIVE);
  241         if (sc->sc_rx_irq == NULL) {
  242                 device_printf(bus, "could not allocate workq irq");
  243                 return;
  244         }
  245 
  246         error = bus_setup_intr(bus, sc->sc_rx_irq, INTR_TYPE_NET | INTR_MPSAFE,
  247                                cvm_oct_do_interrupt, NULL, cvm_oct_device,
  248                                &sc->sc_rx_intr_cookie);
  249         if (error != 0) {
  250                 device_printf(bus, "could not setup workq irq");
  251                 return;
  252         }
  253 
  254 
  255 #ifdef SMP
  256         {
  257                 cvmx_ciu_intx0_t en;
  258                 int core;
  259 
  260                 CPU_FOREACH(core) {
  261                         if (core == PCPU_GET(cpuid))
  262                                 continue;
  263 
  264                         en.u64 = cvmx_read_csr(CVMX_CIU_INTX_EN0(core*2));
  265                         en.s.workq |= (1<<pow_receive_group);
  266                         cvmx_write_csr(CVMX_CIU_INTX_EN0(core*2), en.u64);
  267                 }
  268         }
  269 #endif
  270 }
  271 
  272 
  273 /**
  274  * Free a work queue entry received in a intercept callback.
  275  *
  276  * @param work_queue_entry
  277  *               Work queue entry to free
  278  * @return Zero on success, Negative on failure.
  279  */
  280 int cvm_oct_free_work(void *work_queue_entry)
  281 {
  282         cvmx_wqe_t *work = work_queue_entry;
  283 
  284         int segments = work->word2.s.bufs;
  285         cvmx_buf_ptr_t segment_ptr = work->packet_ptr;
  286 
  287         while (segments--) {
  288                 cvmx_buf_ptr_t next_ptr = *(cvmx_buf_ptr_t *)cvmx_phys_to_ptr(segment_ptr.s.addr-8);
  289                 if (__predict_false(!segment_ptr.s.i))
  290                         cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr), segment_ptr.s.pool, DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE/128));
  291                 segment_ptr = next_ptr;
  292         }
  293         cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
  294 
  295         return 0;
  296 }
  297 
  298 
  299 /**
  300  * Module/ driver initialization. Creates the linux network
  301  * devices.
  302  *
  303  * @return Zero on success
  304  */
  305 int cvm_oct_init_module(device_t bus)
  306 {
  307         device_t dev;
  308         int ifnum;
  309         int num_interfaces;
  310         int interface;
  311         int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
  312         int qos;
  313 
  314         cvm_oct_rx_initialize();
  315         cvm_oct_configure_common_hw(bus);
  316 
  317         cvmx_helper_initialize_packet_io_global();
  318 
  319         /* Change the input group for all ports before input is enabled */
  320         num_interfaces = cvmx_helper_get_number_of_interfaces();
  321         for (interface = 0; interface < num_interfaces; interface++) {
  322                 int num_ports = cvmx_helper_ports_on_interface(interface);
  323                 int port;
  324 
  325                 for (port = 0; port < num_ports; port++) {
  326                         cvmx_pip_prt_tagx_t pip_prt_tagx;
  327                         int pkind = cvmx_helper_get_ipd_port(interface, port);
  328 
  329                         pip_prt_tagx.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(pkind));
  330                         pip_prt_tagx.s.grp = pow_receive_group;
  331                         cvmx_write_csr(CVMX_PIP_PRT_TAGX(pkind), pip_prt_tagx.u64);
  332                 }
  333         }
  334 
  335         cvmx_helper_ipd_and_packet_input_enable();
  336 
  337         memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
  338 
  339         cvm_oct_link_taskq = taskqueue_create("octe link", M_NOWAIT,
  340             taskqueue_thread_enqueue, &cvm_oct_link_taskq);
  341         taskqueue_start_threads(&cvm_oct_link_taskq, 1, PI_NET,
  342             "octe link taskq");
  343 
  344         /* Initialize the FAU used for counting packet buffers that need to be freed */
  345         cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
  346 
  347         ifnum = 0;
  348         num_interfaces = cvmx_helper_get_number_of_interfaces();
  349         for (interface = 0; interface < num_interfaces; interface++) {
  350                 cvmx_helper_interface_mode_t imode = cvmx_helper_interface_get_mode(interface);
  351                 int num_ports = cvmx_helper_ports_on_interface(interface);
  352                 int port;
  353 
  354                 for (port = cvmx_helper_get_ipd_port(interface, 0);
  355                      port < cvmx_helper_get_ipd_port(interface, num_ports);
  356                      ifnum++, port++) {
  357                         cvm_oct_private_t *priv;
  358                         struct ifnet *ifp;
  359                         
  360                         dev = BUS_ADD_CHILD(bus, 0, "octe", ifnum);
  361                         if (dev != NULL)
  362                                 ifp = if_alloc(IFT_ETHER);
  363                         if (dev == NULL || ifp == NULL) {
  364                                 printf("Failed to allocate ethernet device for interface %d port %d\n", interface, port);
  365                                 continue;
  366                         }
  367 
  368                         /* Initialize the device private structure. */
  369                         device_probe(dev);
  370                         priv = device_get_softc(dev);
  371                         priv->dev = dev;
  372                         priv->ifp = ifp;
  373                         priv->imode = imode;
  374                         priv->port = port;
  375                         priv->queue = cvmx_pko_get_base_queue(priv->port);
  376                         priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
  377                         for (qos = 0; qos < cvmx_pko_get_num_queues(port); qos++)
  378                                 cvmx_fau_atomic_write32(priv->fau+qos*4, 0);
  379                         TASK_INIT(&priv->link_task, 0, cvm_oct_update_link, priv);
  380 
  381                         switch (priv->imode) {
  382 
  383                         /* These types don't support ports to IPD/PKO */
  384                         case CVMX_HELPER_INTERFACE_MODE_DISABLED:
  385                         case CVMX_HELPER_INTERFACE_MODE_PCIE:
  386                         case CVMX_HELPER_INTERFACE_MODE_PICMG:
  387                                 break;
  388 
  389                         case CVMX_HELPER_INTERFACE_MODE_NPI:
  390                                 priv->init = cvm_oct_common_init;
  391                                 priv->uninit = cvm_oct_common_uninit;
  392                                 device_set_desc(dev, "Cavium Octeon NPI Ethernet");
  393                                 break;
  394 
  395                         case CVMX_HELPER_INTERFACE_MODE_XAUI:
  396                                 priv->init = cvm_oct_xaui_init;
  397                                 priv->uninit = cvm_oct_common_uninit;
  398                                 device_set_desc(dev, "Cavium Octeon XAUI Ethernet");
  399                                 break;
  400 
  401                         case CVMX_HELPER_INTERFACE_MODE_LOOP:
  402                                 priv->init = cvm_oct_common_init;
  403                                 priv->uninit = cvm_oct_common_uninit;
  404                                 device_set_desc(dev, "Cavium Octeon LOOP Ethernet");
  405                                 break;
  406 
  407                         case CVMX_HELPER_INTERFACE_MODE_SGMII:
  408                                 priv->init = cvm_oct_sgmii_init;
  409                                 priv->uninit = cvm_oct_common_uninit;
  410                                 device_set_desc(dev, "Cavium Octeon SGMII Ethernet");
  411                                 break;
  412 
  413                         case CVMX_HELPER_INTERFACE_MODE_SPI:
  414                                 priv->init = cvm_oct_spi_init;
  415                                 priv->uninit = cvm_oct_spi_uninit;
  416                                 device_set_desc(dev, "Cavium Octeon SPI Ethernet");
  417                                 break;
  418 
  419                         case CVMX_HELPER_INTERFACE_MODE_RGMII:
  420                                 priv->init = cvm_oct_rgmii_init;
  421                                 priv->uninit = cvm_oct_rgmii_uninit;
  422                                 device_set_desc(dev, "Cavium Octeon RGMII Ethernet");
  423                                 break;
  424 
  425                         case CVMX_HELPER_INTERFACE_MODE_GMII:
  426                                 priv->init = cvm_oct_rgmii_init;
  427                                 priv->uninit = cvm_oct_rgmii_uninit;
  428                                 device_set_desc(dev, "Cavium Octeon GMII Ethernet");
  429                                 break;
  430                         }
  431 
  432                         ifp->if_softc = priv;
  433 
  434                         if (!priv->init) {
  435                                 printf("octe%d: unsupported device type interface %d, port %d\n",
  436                                        ifnum, interface, priv->port);
  437                                 if_free(ifp);
  438                         } else if (priv->init(ifp) != 0) {
  439                                 printf("octe%d: failed to register device for interface %d, port %d\n",
  440                                        ifnum, interface, priv->port);
  441                                 if_free(ifp);
  442                         } else {
  443                                 cvm_oct_device[priv->port] = ifp;
  444                                 fau -= cvmx_pko_get_num_queues(priv->port) * sizeof(uint32_t);
  445                         }
  446                 }
  447         }
  448 
  449         if (INTERRUPT_LIMIT) {
  450                 /* Set the POW timer rate to give an interrupt at most INTERRUPT_LIMIT times per second */
  451                 cvmx_write_csr(CVMX_POW_WQ_INT_PC, cvmx_clock_get_rate(CVMX_CLOCK_CORE)/((INTERRUPT_LIMIT+1)*16*256)<<8);
  452 
  453                 /* Enable POW timer interrupt. It will count when there are packets available */
  454                 cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0x1ful<<24);
  455         } else {
  456                 /* Enable POW interrupt when our port has at least one packet */
  457                 cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0x1001);
  458         }
  459 
  460         callout_init(&cvm_oct_poll_timer, 1);
  461         callout_reset(&cvm_oct_poll_timer, hz, cvm_do_timer, NULL);
  462 
  463         return 0;
  464 }
  465 
  466 
  467 /**
  468  * Module / driver shutdown
  469  *
  470  * @return Zero on success
  471  */
  472 void cvm_oct_cleanup_module(device_t bus)
  473 {
  474         int port;
  475         struct octebus_softc *sc = device_get_softc(bus);
  476 
  477         /* Disable POW interrupt */
  478         cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
  479 
  480         /* Free the interrupt handler */
  481         bus_teardown_intr(bus, sc->sc_rx_irq, sc->sc_rx_intr_cookie);
  482 
  483         callout_stop(&cvm_oct_poll_timer);
  484         cvm_oct_rx_shutdown();
  485 
  486         cvmx_helper_shutdown_packet_io_global();
  487 
  488         /* Free the ethernet devices */
  489         for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
  490                 if (cvm_oct_device[port]) {
  491                         cvm_oct_tx_shutdown(cvm_oct_device[port]);
  492 #if 0
  493                         unregister_netdev(cvm_oct_device[port]);
  494                         kfree(cvm_oct_device[port]);
  495 #else
  496                         panic("%s: need to detach and free interface.", __func__);
  497 #endif
  498                         cvm_oct_device[port] = NULL;
  499                 }
  500         }
  501         /* Free the HW pools */
  502         cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE, num_packet_buffers);
  503         cvm_oct_mem_empty_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE, num_packet_buffers);
  504 
  505         if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
  506                 cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL, CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, cvm_oct_num_output_buffers);
  507 
  508         /* Disable FPA, all buffers are free, not done by helper shutdown. */
  509         cvmx_fpa_disable();
  510 }

Cache object: 3b8229ee96827547b82d4a10123e5152


[ 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.