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/contrib/ncsw/Peripherals/FM/Port/fman_port.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  * Copyright 2008-2012 Freescale Semiconductor Inc.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions are met:
    6  *     * Redistributions of source code must retain the above copyright
    7  *       notice, this list of conditions and the following disclaimer.
    8  *     * Redistributions in binary form must reproduce the above copyright
    9  *       notice, this list of conditions and the following disclaimer in the
   10  *       documentation and/or other materials provided with the distribution.
   11  *     * Neither the name of Freescale Semiconductor nor the
   12  *       names of its contributors may be used to endorse or promote products
   13  *       derived from this software without specific prior written permission.
   14  *
   15  *
   16  * ALTERNATIVELY, this software may be distributed under the terms of the
   17  * GNU General Public License ("GPL") as published by the Free Software
   18  * Foundation, either version 2 of that License or (at your option) any
   19  * later version.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
   22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   24  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
   25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 
   34 #include "common/general.h"
   35 
   36 #include "fman_common.h"
   37 #include "fsl_fman_port.h"
   38 
   39 
   40 /* problem Eyal: the following should not be here*/
   41 #define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME        0x00000028
   42 
   43 static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg)
   44 {
   45     if (cfg->errata_A006675)
   46         return NIA_ENG_FM_CTL |
   47             NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
   48     else
   49         return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
   50 }
   51 
   52 static int init_bmi_rx(struct fman_port *port,
   53         struct fman_port_cfg *cfg,
   54         struct fman_port_params *params)
   55 {
   56     struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
   57     uint32_t tmp;
   58 
   59     /* Rx Configuration register */
   60     tmp = 0;
   61     if (port->im_en)
   62         tmp |= BMI_PORT_CFG_IM;
   63     else if (cfg->discard_override)
   64         tmp |= BMI_PORT_CFG_FDOVR;
   65     iowrite32be(tmp, &regs->fmbm_rcfg);
   66 
   67     /* DMA attributes */
   68     tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
   69     if (cfg->dma_ic_stash_on)
   70         tmp |= BMI_DMA_ATTR_IC_STASH_ON;
   71     if (cfg->dma_header_stash_on)
   72         tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
   73     if (cfg->dma_sg_stash_on)
   74         tmp |= BMI_DMA_ATTR_SG_STASH_ON;
   75     if (cfg->dma_write_optimize)
   76         tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
   77     iowrite32be(tmp, &regs->fmbm_rda);
   78 
   79     /* Rx FIFO parameters */
   80     tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) <<
   81             BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
   82     tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1;
   83     iowrite32be(tmp, &regs->fmbm_rfp);
   84 
   85     if (cfg->excessive_threshold_register)
   86         /* always allow access to the extra resources */
   87         iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
   88 
   89     /* Frame end data */
   90     tmp = (uint32_t)cfg->checksum_bytes_ignore <<
   91             BMI_RX_FRAME_END_CS_IGNORE_SHIFT;
   92     tmp |= (uint32_t)cfg->rx_cut_end_bytes <<
   93             BMI_RX_FRAME_END_CUT_SHIFT;
   94     if (cfg->errata_A006320)
   95         tmp &= 0xffe0ffff;
   96     iowrite32be(tmp, &regs->fmbm_rfed);
   97 
   98     /* Internal context parameters */
   99     tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
  100             BMI_IC_TO_EXT_SHIFT;
  101     tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
  102             BMI_IC_FROM_INT_SHIFT;
  103     tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
  104     iowrite32be(tmp, &regs->fmbm_ricp);
  105 
  106     /* Internal buffer offset */
  107     tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
  108             << BMI_INT_BUF_MARG_SHIFT;
  109     iowrite32be(tmp, &regs->fmbm_rim);
  110 
  111     /* External buffer margins */
  112     if (!port->im_en)
  113     {
  114         tmp = (uint32_t)cfg->ext_buf_start_margin <<
  115                 BMI_EXT_BUF_MARG_START_SHIFT;
  116         tmp |= (uint32_t)cfg->ext_buf_end_margin;
  117         if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
  118             tmp |= BMI_SG_DISABLE;
  119         iowrite32be(tmp, &regs->fmbm_rebm);
  120     }
  121 
  122     /* Frame attributes */
  123     tmp = BMI_CMD_RX_MR_DEF;
  124     if (!port->im_en)
  125     {
  126         tmp |= BMI_CMD_ATTR_ORDER;
  127         tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
  128         if (cfg->sync_req)
  129             tmp |= BMI_CMD_ATTR_SYNC;
  130     }
  131     iowrite32be(tmp, &regs->fmbm_rfca);
  132 
  133     /* NIA */
  134     if (port->im_en)
  135         tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX;
  136     else
  137     {
  138         tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
  139         tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg);
  140     }
  141     iowrite32be(tmp, &regs->fmbm_rfne);
  142 
  143     /* Enqueue NIA */
  144     iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
  145 
  146     /* Default/error queues */
  147     if (!port->im_en)
  148     {
  149         iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_rfqid);
  150         iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_refqid);
  151     }
  152 
  153     /* Discard/error masks */
  154     iowrite32be(params->discard_mask, &regs->fmbm_rfsdm);
  155     iowrite32be(params->err_mask, &regs->fmbm_rfsem);
  156 
  157     /* Statistics counters */
  158     tmp = 0;
  159     if (cfg->stats_counters_enable)
  160         tmp = BMI_COUNTERS_EN;
  161     iowrite32be(tmp, &regs->fmbm_rstc);
  162 
  163     /* Performance counters */
  164     fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
  165     tmp = 0;
  166     if (cfg->perf_counters_enable)
  167         tmp = BMI_COUNTERS_EN;
  168     iowrite32be(tmp, &regs->fmbm_rpc);
  169 
  170     return 0;
  171 }
  172 
  173 static int init_bmi_tx(struct fman_port *port,
  174         struct fman_port_cfg *cfg,
  175         struct fman_port_params *params)
  176 {
  177     struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
  178     uint32_t tmp;
  179 
  180     /* Tx Configuration register */
  181     tmp = 0;
  182     if (port->im_en)
  183         tmp |= BMI_PORT_CFG_IM;
  184     iowrite32be(tmp, &regs->fmbm_tcfg);
  185 
  186     /* DMA attributes */
  187     tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
  188     if (cfg->dma_ic_stash_on)
  189         tmp |= BMI_DMA_ATTR_IC_STASH_ON;
  190     if (cfg->dma_header_stash_on)
  191         tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
  192     if (cfg->dma_sg_stash_on)
  193         tmp |= BMI_DMA_ATTR_SG_STASH_ON;
  194     iowrite32be(tmp, &regs->fmbm_tda);
  195 
  196     /* Tx FIFO parameters */
  197     tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) <<
  198             BMI_TX_FIFO_MIN_FILL_SHIFT;
  199     tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
  200             BMI_FIFO_PIPELINE_DEPTH_SHIFT;
  201     tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level /
  202             FMAN_PORT_BMI_FIFO_UNITS - 1);
  203     iowrite32be(tmp, &regs->fmbm_tfp);
  204 
  205     /* Frame end data */
  206     tmp = (uint32_t)cfg->checksum_bytes_ignore <<
  207             BMI_FRAME_END_CS_IGNORE_SHIFT;
  208     iowrite32be(tmp, &regs->fmbm_tfed);
  209 
  210     /* Internal context parameters */
  211     if (!port->im_en)
  212     {
  213         tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
  214                 BMI_IC_TO_EXT_SHIFT;
  215         tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
  216                 BMI_IC_FROM_INT_SHIFT;
  217         tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
  218         iowrite32be(tmp, &regs->fmbm_ticp);
  219     }
  220     /* Frame attributes */
  221     tmp = BMI_CMD_TX_MR_DEF;
  222     if (port->im_en)
  223         tmp |= BMI_CMD_MR_DEAS;
  224     else
  225     {
  226         tmp |= BMI_CMD_ATTR_ORDER;
  227         tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
  228     }
  229     iowrite32be(tmp, &regs->fmbm_tfca);
  230 
  231     /* Dequeue NIA + enqueue NIA */
  232     if (port->im_en)
  233     {
  234         iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfdne);
  235         iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfene);
  236     }
  237     else
  238     {
  239         iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
  240         iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
  241         if (cfg->fmbm_tfne_has_features)
  242             iowrite32be(!params->dflt_fqid ?
  243                 BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
  244                 NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
  245         if (!params->dflt_fqid && params->dont_release_buf)
  246         {
  247             iowrite32be(0x00FFFFFF, &regs->fmbm_tcfqid);
  248             iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, &regs->fmbm_tfene);
  249             if (cfg->fmbm_tfne_has_features)
  250                 iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN, &regs->fmbm_tfne);
  251         }
  252     }
  253 
  254     /* Confirmation/error queues */
  255     if (!port->im_en)
  256     {
  257         if (params->dflt_fqid || !params->dont_release_buf)
  258             iowrite32be(params->dflt_fqid & 0x00FFFFFF, &regs->fmbm_tcfqid);
  259         iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_tefqid);
  260     }
  261     /* Statistics counters */
  262     tmp = 0;
  263     if (cfg->stats_counters_enable)
  264         tmp = BMI_COUNTERS_EN;
  265     iowrite32be(tmp, &regs->fmbm_tstc);
  266 
  267     /* Performance counters */
  268     fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
  269     tmp = 0;
  270     if (cfg->perf_counters_enable)
  271         tmp = BMI_COUNTERS_EN;
  272     iowrite32be(tmp, &regs->fmbm_tpc);
  273 
  274     return 0;
  275 }
  276 
  277 static int init_bmi_oh(struct fman_port *port,
  278         struct fman_port_cfg *cfg,
  279         struct fman_port_params *params)
  280 {
  281     struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
  282     uint32_t tmp;
  283 
  284     /* OP Configuration register */
  285     tmp = 0;
  286     if (cfg->discard_override)
  287         tmp |= BMI_PORT_CFG_FDOVR;
  288     iowrite32be(tmp, &regs->fmbm_ocfg);
  289 
  290     /* DMA attributes */
  291     tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
  292     if (cfg->dma_ic_stash_on)
  293         tmp |= BMI_DMA_ATTR_IC_STASH_ON;
  294     if (cfg->dma_header_stash_on)
  295         tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
  296     if (cfg->dma_sg_stash_on)
  297         tmp |= BMI_DMA_ATTR_SG_STASH_ON;
  298     if (cfg->dma_write_optimize)
  299         tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
  300     iowrite32be(tmp, &regs->fmbm_oda);
  301 
  302     /* Tx FIFO parameters */
  303     tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
  304             BMI_FIFO_PIPELINE_DEPTH_SHIFT;
  305     iowrite32be(tmp, &regs->fmbm_ofp);
  306 
  307     /* Internal context parameters */
  308     tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
  309             BMI_IC_TO_EXT_SHIFT;
  310     tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
  311             BMI_IC_FROM_INT_SHIFT;
  312     tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
  313     iowrite32be(tmp, &regs->fmbm_oicp);
  314 
  315     /* Frame attributes */
  316     tmp = BMI_CMD_OP_MR_DEF;
  317     tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
  318     if (cfg->sync_req)
  319         tmp |= BMI_CMD_ATTR_SYNC;
  320     if (port->type == E_FMAN_PORT_TYPE_OP)
  321         tmp |= BMI_CMD_ATTR_ORDER;
  322     iowrite32be(tmp, &regs->fmbm_ofca);
  323 
  324     /* Internal buffer offset */
  325     tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
  326             << BMI_INT_BUF_MARG_SHIFT;
  327     iowrite32be(tmp, &regs->fmbm_oim);
  328 
  329     /* Dequeue NIA */
  330     iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_ofdne);
  331 
  332     /* NIA and Enqueue NIA */
  333     if (port->type == E_FMAN_PORT_TYPE_HC) {
  334         iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC,
  335                 &regs->fmbm_ofne);
  336         iowrite32be(NIA_ENG_QMI_ENQ, &regs->fmbm_ofene);
  337     } else {
  338         iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg),
  339                 &regs->fmbm_ofne);
  340         iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR,
  341                 &regs->fmbm_ofene);
  342     }
  343 
  344     /* Default/error queues */
  345     iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_ofqid);
  346     iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_oefqid);
  347 
  348     /* Discard/error masks */
  349     if (port->type == E_FMAN_PORT_TYPE_OP) {
  350         iowrite32be(params->discard_mask, &regs->fmbm_ofsdm);
  351         iowrite32be(params->err_mask, &regs->fmbm_ofsem);
  352     }
  353 
  354     /* Statistics counters */
  355     tmp = 0;
  356     if (cfg->stats_counters_enable)
  357         tmp = BMI_COUNTERS_EN;
  358     iowrite32be(tmp, &regs->fmbm_ostc);
  359 
  360     /* Performance counters */
  361     fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
  362     tmp = 0;
  363     if (cfg->perf_counters_enable)
  364         tmp = BMI_COUNTERS_EN;
  365     iowrite32be(tmp, &regs->fmbm_opc);
  366 
  367     return 0;
  368 }
  369 
  370 static int init_qmi(struct fman_port *port,
  371         struct fman_port_cfg *cfg,
  372         struct fman_port_params *params)
  373 {
  374     struct fman_port_qmi_regs *regs = port->qmi_regs;
  375     uint32_t tmp;
  376 
  377     tmp = 0;
  378     if (cfg->queue_counters_enable)
  379         tmp |= QMI_PORT_CFG_EN_COUNTERS;
  380     iowrite32be(tmp, &regs->fmqm_pnc);
  381 
  382     /* Rx port configuration */
  383     if ((port->type == E_FMAN_PORT_TYPE_RX) ||
  384             (port->type == E_FMAN_PORT_TYPE_RX_10G)) {
  385         /* Enqueue NIA */
  386         iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
  387         return 0;
  388     }
  389 
  390     /* Continue with Tx and O/H port configuration */
  391     if ((port->type == E_FMAN_PORT_TYPE_TX) ||
  392             (port->type == E_FMAN_PORT_TYPE_TX_10G)) {
  393         /* Enqueue NIA */
  394         iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
  395                 &regs->fmqm_pnen);
  396         /* Dequeue NIA */
  397         iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
  398     } else {
  399         /* Enqueue NIA */
  400         iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
  401         /* Dequeue NIA */
  402         iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, &regs->fmqm_pndn);
  403     }
  404 
  405     /* Dequeue Configuration register */
  406     tmp = 0;
  407     if (cfg->deq_high_pri)
  408         tmp |= QMI_DEQ_CFG_PRI;
  409 
  410     switch (cfg->deq_type) {
  411     case E_FMAN_PORT_DEQ_BY_PRI:
  412         tmp |= QMI_DEQ_CFG_TYPE1;
  413         break;
  414     case E_FMAN_PORT_DEQ_ACTIVE_FQ:
  415         tmp |= QMI_DEQ_CFG_TYPE2;
  416         break;
  417     case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
  418         tmp |= QMI_DEQ_CFG_TYPE3;
  419         break;
  420     default:
  421         return -EINVAL;
  422     }
  423 
  424     if (cfg->qmi_deq_options_support) {
  425         if ((port->type == E_FMAN_PORT_TYPE_HC) &&
  426             (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH))
  427             return -EINVAL;
  428 
  429         switch (cfg->deq_prefetch_opt) {
  430         case E_FMAN_PORT_DEQ_NO_PREFETCH:
  431             break;
  432         case E_FMAN_PORT_DEQ_PART_PREFETCH:
  433             tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
  434             break;
  435         case E_FMAN_PORT_DEQ_FULL_PREFETCH:
  436             tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
  437             break;
  438         default:
  439             return -EINVAL;
  440         }
  441     }
  442     tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) <<
  443             QMI_DEQ_CFG_SP_SHIFT;
  444     tmp |= cfg->deq_byte_cnt;
  445     iowrite32be(tmp, &regs->fmqm_pndc);
  446 
  447     return 0;
  448 }
  449 
  450 static void get_rx_stats_reg(struct fman_port *port,
  451         enum fman_port_stats_counters counter,
  452         uint32_t **stats_reg)
  453 {
  454     struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
  455 
  456     switch (counter) {
  457     case E_FMAN_PORT_STATS_CNT_FRAME:
  458         *stats_reg = &regs->fmbm_rfrc;
  459         break;
  460     case E_FMAN_PORT_STATS_CNT_DISCARD:
  461         *stats_reg = &regs->fmbm_rfdc;
  462         break;
  463     case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
  464         *stats_reg = &regs->fmbm_rbdc;
  465         break;
  466     case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME:
  467         *stats_reg = &regs->fmbm_rfbc;
  468         break;
  469     case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME:
  470         *stats_reg = &regs->fmbm_rlfc;
  471         break;
  472     case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF:
  473         *stats_reg = &regs->fmbm_rodc;
  474         break;
  475     case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
  476         *stats_reg = &regs->fmbm_rffc;
  477         break;
  478     case E_FMAN_PORT_STATS_CNT_DMA_ERR:
  479         *stats_reg = &regs->fmbm_rfldec;
  480         break;
  481     default:
  482         *stats_reg = NULL;
  483     }
  484 }
  485 
  486 static void get_tx_stats_reg(struct fman_port *port,
  487         enum fman_port_stats_counters counter,
  488         uint32_t **stats_reg)
  489 {
  490     struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
  491 
  492     switch (counter) {
  493     case E_FMAN_PORT_STATS_CNT_FRAME:
  494         *stats_reg = &regs->fmbm_tfrc;
  495         break;
  496     case E_FMAN_PORT_STATS_CNT_DISCARD:
  497         *stats_reg = &regs->fmbm_tfdc;
  498         break;
  499     case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
  500         *stats_reg = &regs->fmbm_tbdc;
  501         break;
  502     case E_FMAN_PORT_STATS_CNT_LEN_ERR:
  503         *stats_reg = &regs->fmbm_tfledc;
  504         break;
  505     case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
  506         *stats_reg = &regs->fmbm_tfufdc;
  507         break;
  508     default:
  509         *stats_reg = NULL;
  510     }
  511 }
  512 
  513 static void get_oh_stats_reg(struct fman_port *port,
  514         enum fman_port_stats_counters counter,
  515         uint32_t **stats_reg)
  516 {
  517     struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
  518 
  519     switch (counter) {
  520     case E_FMAN_PORT_STATS_CNT_FRAME:
  521         *stats_reg = &regs->fmbm_ofrc;
  522         break;
  523     case E_FMAN_PORT_STATS_CNT_DISCARD:
  524         *stats_reg = &regs->fmbm_ofdc;
  525         break;
  526     case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
  527         *stats_reg = &regs->fmbm_obdc;
  528         break;
  529     case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
  530         *stats_reg = &regs->fmbm_offc;
  531         break;
  532     case E_FMAN_PORT_STATS_CNT_DMA_ERR:
  533         *stats_reg = &regs->fmbm_ofldec;
  534         break;
  535     case E_FMAN_PORT_STATS_CNT_LEN_ERR:
  536         *stats_reg = &regs->fmbm_ofledc;
  537         break;
  538     case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
  539         *stats_reg = &regs->fmbm_ofufdc;
  540         break;
  541     case E_FMAN_PORT_STATS_CNT_WRED_DISCARD:
  542         *stats_reg = &regs->fmbm_ofwdc;
  543         break;
  544     default:
  545         *stats_reg = NULL;
  546     }
  547 }
  548 
  549 static void get_rx_perf_reg(struct fman_port *port,
  550         enum fman_port_perf_counters counter,
  551         uint32_t **perf_reg)
  552 {
  553     struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
  554 
  555     switch (counter) {
  556     case E_FMAN_PORT_PERF_CNT_CYCLE:
  557         *perf_reg = &regs->fmbm_rccn;
  558         break;
  559     case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
  560         *perf_reg = &regs->fmbm_rtuc;
  561         break;
  562     case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
  563         *perf_reg = &regs->fmbm_rrquc;
  564         break;
  565     case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
  566         *perf_reg = &regs->fmbm_rduc;
  567         break;
  568     case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
  569         *perf_reg = &regs->fmbm_rfuc;
  570         break;
  571     case E_FMAN_PORT_PERF_CNT_RX_PAUSE:
  572         *perf_reg = &regs->fmbm_rpac;
  573         break;
  574     default:
  575         *perf_reg = NULL;
  576     }
  577 }
  578 
  579 static void get_tx_perf_reg(struct fman_port *port,
  580         enum fman_port_perf_counters counter,
  581         uint32_t **perf_reg)
  582 {
  583     struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
  584 
  585     switch (counter) {
  586     case E_FMAN_PORT_PERF_CNT_CYCLE:
  587         *perf_reg = &regs->fmbm_tccn;
  588         break;
  589     case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
  590         *perf_reg = &regs->fmbm_ttuc;
  591         break;
  592     case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
  593         *perf_reg = &regs->fmbm_ttcquc;
  594         break;
  595     case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
  596         *perf_reg = &regs->fmbm_tduc;
  597         break;
  598     case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
  599         *perf_reg = &regs->fmbm_tfuc;
  600         break;
  601     default:
  602         *perf_reg = NULL;
  603     }
  604 }
  605 
  606 static void get_oh_perf_reg(struct fman_port *port,
  607         enum fman_port_perf_counters counter,
  608         uint32_t **perf_reg)
  609 {
  610     struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
  611 
  612     switch (counter) {
  613     case E_FMAN_PORT_PERF_CNT_CYCLE:
  614         *perf_reg = &regs->fmbm_occn;
  615         break;
  616     case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
  617         *perf_reg = &regs->fmbm_otuc;
  618         break;
  619     case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
  620         *perf_reg = &regs->fmbm_oduc;
  621         break;
  622     case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
  623         *perf_reg = &regs->fmbm_ofuc;
  624         break;
  625     default:
  626         *perf_reg = NULL;
  627     }
  628 }
  629 
  630 static void get_qmi_counter_reg(struct fman_port *port,
  631         enum fman_port_qmi_counters  counter,
  632         uint32_t **queue_reg)
  633 {
  634     struct fman_port_qmi_regs *regs = port->qmi_regs;
  635 
  636     switch (counter) {
  637     case E_FMAN_PORT_ENQ_TOTAL:
  638         *queue_reg = &regs->fmqm_pnetfc;
  639         break;
  640     case E_FMAN_PORT_DEQ_TOTAL:
  641         if ((port->type == E_FMAN_PORT_TYPE_RX) ||
  642                 (port->type == E_FMAN_PORT_TYPE_RX_10G))
  643             /* Counter not available for Rx ports */
  644             *queue_reg = NULL;
  645         else
  646             *queue_reg = &regs->fmqm_pndtfc;
  647         break;
  648     case E_FMAN_PORT_DEQ_FROM_DFLT:
  649         if ((port->type == E_FMAN_PORT_TYPE_RX) ||
  650                 (port->type == E_FMAN_PORT_TYPE_RX_10G))
  651             /* Counter not available for Rx ports */
  652             *queue_reg = NULL;
  653         else
  654             *queue_reg = &regs->fmqm_pndfdc;
  655         break;
  656     case E_FMAN_PORT_DEQ_CONFIRM:
  657         if ((port->type == E_FMAN_PORT_TYPE_RX) ||
  658                 (port->type == E_FMAN_PORT_TYPE_RX_10G))
  659             /* Counter not available for Rx ports */
  660             *queue_reg = NULL;
  661         else
  662             *queue_reg = &regs->fmqm_pndcc;
  663         break;
  664     default:
  665         *queue_reg = NULL;
  666     }
  667 }
  668 
  669 void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type)
  670 {
  671     cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP;
  672     cfg->dma_ic_stash_on = FALSE;
  673     cfg->dma_header_stash_on = FALSE;
  674     cfg->dma_sg_stash_on = FALSE;
  675     cfg->dma_write_optimize = TRUE;
  676     cfg->color = E_FMAN_PORT_COLOR_GREEN;
  677     cfg->discard_override = FALSE;
  678     cfg->checksum_bytes_ignore = 0;
  679     cfg->rx_cut_end_bytes = 4;
  680     cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
  681     cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
  682     cfg->rx_fd_bits = 0;
  683     cfg->ic_ext_offset = 0;
  684     cfg->ic_int_offset = 0;
  685     cfg->ic_size = 0;
  686     cfg->int_buf_start_margin = 0;
  687     cfg->ext_buf_start_margin = 0;
  688     cfg->ext_buf_end_margin = 0;
  689     cfg->tx_fifo_min_level  = 0;
  690     cfg->tx_fifo_low_comf_level = (5 * KILOBYTE);
  691     cfg->stats_counters_enable = TRUE;
  692     cfg->perf_counters_enable = TRUE;
  693     cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI;
  694 
  695     if (type == E_FMAN_PORT_TYPE_HC) {
  696         cfg->sync_req = FALSE;
  697         cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH;
  698     } else {
  699         cfg->sync_req = TRUE;
  700         cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH;
  701     }
  702 
  703     if (type == E_FMAN_PORT_TYPE_TX_10G) {
  704         cfg->tx_fifo_deq_pipeline_depth = 4;
  705         cfg->deq_high_pri = TRUE;
  706         cfg->deq_byte_cnt = 0x1400;
  707     } else {
  708         if ((type == E_FMAN_PORT_TYPE_HC) ||
  709                 (type == E_FMAN_PORT_TYPE_OP))
  710             cfg->tx_fifo_deq_pipeline_depth = 2;
  711         else
  712             cfg->tx_fifo_deq_pipeline_depth = 1;
  713 
  714         cfg->deq_high_pri = FALSE;
  715         cfg->deq_byte_cnt = 0x400;
  716     }
  717     cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
  718 }
  719 
  720 static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid)
  721 {
  722     uint32_t *bp_reg, tmp;
  723     uint8_t i, id;
  724 
  725     /* Find the pool */
  726     bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
  727     for (i = 0;
  728          (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM));
  729          i++) {
  730         tmp = ioread32be(&bp_reg[i]);
  731         id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >>
  732                 BMI_EXT_BUF_POOL_ID_SHIFT);
  733 
  734         if (id == bpid)
  735             break;
  736     }
  737 
  738     return i;
  739 }
  740 
  741 int fman_port_init(struct fman_port *port,
  742         struct fman_port_cfg *cfg,
  743         struct fman_port_params *params)
  744 {
  745     int err;
  746 
  747     /* Init BMI registers */
  748     switch (port->type) {
  749     case E_FMAN_PORT_TYPE_RX:
  750     case E_FMAN_PORT_TYPE_RX_10G:
  751         err = init_bmi_rx(port, cfg, params);
  752         break;
  753     case E_FMAN_PORT_TYPE_TX:
  754     case E_FMAN_PORT_TYPE_TX_10G:
  755         err = init_bmi_tx(port, cfg, params);
  756         break;
  757     case E_FMAN_PORT_TYPE_OP:
  758     case E_FMAN_PORT_TYPE_HC:
  759         err = init_bmi_oh(port, cfg, params);
  760         break;
  761     default:
  762         return -EINVAL;
  763     }
  764 
  765     if (err)
  766         return err;
  767 
  768     /* Init QMI registers */
  769     if (!port->im_en)
  770     {
  771         err = init_qmi(port, cfg, params);
  772         return err;
  773     }
  774     return 0;
  775 }
  776 
  777 int fman_port_enable(struct fman_port *port)
  778 {
  779     uint32_t *bmi_cfg_reg, tmp;
  780     bool rx_port;
  781 
  782     switch (port->type) {
  783     case E_FMAN_PORT_TYPE_RX:
  784     case E_FMAN_PORT_TYPE_RX_10G:
  785         bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
  786         rx_port = TRUE;
  787         break;
  788     case E_FMAN_PORT_TYPE_TX:
  789     case E_FMAN_PORT_TYPE_TX_10G:
  790         bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
  791         rx_port = FALSE;
  792         break;
  793     case E_FMAN_PORT_TYPE_OP:
  794     case E_FMAN_PORT_TYPE_HC:
  795         bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
  796         rx_port = FALSE;
  797         break;
  798     default:
  799         return -EINVAL;
  800     }
  801 
  802     /* Enable QMI */
  803     if (!rx_port) {
  804         tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
  805         iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
  806     }
  807 
  808     /* Enable BMI */
  809     tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
  810     iowrite32be(tmp, bmi_cfg_reg);
  811 
  812     return 0;
  813 }
  814 
  815 int fman_port_disable(const struct fman_port *port)
  816 {
  817     uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp;
  818     bool rx_port, failure = FALSE;
  819     int count;
  820 
  821     switch (port->type) {
  822     case E_FMAN_PORT_TYPE_RX:
  823     case E_FMAN_PORT_TYPE_RX_10G:
  824         bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
  825         bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
  826         rx_port = TRUE;
  827         break;
  828     case E_FMAN_PORT_TYPE_TX:
  829     case E_FMAN_PORT_TYPE_TX_10G:
  830         bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
  831         bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
  832         rx_port = FALSE;
  833         break;
  834     case E_FMAN_PORT_TYPE_OP:
  835     case E_FMAN_PORT_TYPE_HC:
  836         bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
  837         bmi_status_reg = &port->bmi_regs->oh.fmbm_ost;
  838         rx_port = FALSE;
  839         break;
  840     default:
  841         return -EINVAL;
  842     }
  843 
  844     /* Disable QMI */
  845     if (!rx_port) {
  846         tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
  847         iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
  848 
  849         /* Wait for QMI to finish FD handling */
  850         count = 100;
  851         do {
  852             DELAY(10);
  853             tmp = ioread32be(&port->qmi_regs->fmqm_pns);
  854         } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
  855 
  856         if (count == 0)
  857         {
  858             /* Timeout */
  859             failure = TRUE;
  860         }
  861     }
  862 
  863     /* Disable BMI */
  864     tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
  865     iowrite32be(tmp, bmi_cfg_reg);
  866 
  867     /* Wait for graceful stop end */
  868     count = 500;
  869     do {
  870         DELAY(10);
  871         tmp = ioread32be(bmi_status_reg);
  872     } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
  873 
  874     if (count == 0)
  875     {
  876         /* Timeout */
  877         failure = TRUE;
  878     }
  879 
  880     if (failure)
  881         return -EBUSY;
  882 
  883     return 0;
  884 }
  885 
  886 int fman_port_set_bpools(const struct fman_port *port,
  887         const struct fman_port_bpools *bp)
  888 {
  889     uint32_t tmp, *bp_reg, *bp_depl_reg;
  890     uint8_t i, max_bp_num;
  891     bool grp_depl_used = FALSE, rx_port;
  892 
  893     switch (port->type) {
  894     case E_FMAN_PORT_TYPE_RX:
  895     case E_FMAN_PORT_TYPE_RX_10G:
  896         max_bp_num = port->ext_pools_num;
  897         rx_port = TRUE;
  898         bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
  899         bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
  900         break;
  901     case E_FMAN_PORT_TYPE_OP:
  902         if (port->fm_rev_maj != 4)
  903             return -EINVAL;
  904         max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM;
  905         rx_port = FALSE;
  906         bp_reg = port->bmi_regs->oh.fmbm_oebmpi;
  907         bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd;
  908         break;
  909     default:
  910         return -EINVAL;
  911     }
  912 
  913     if (rx_port) {
  914         /* Check buffers are provided in ascending order */
  915         for (i = 0;
  916              (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1));
  917              i++) {
  918             if (bp->bpool[i].size > bp->bpool[i+1].size)
  919                 return -EINVAL;
  920         }
  921     }
  922 
  923     /* Set up external buffers pools */
  924     for (i = 0; i < bp->count; i++) {
  925         tmp = BMI_EXT_BUF_POOL_VALID;
  926         tmp |= ((uint32_t)bp->bpool[i].bpid <<
  927             BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
  928 
  929         if (rx_port) {
  930             if (bp->counters_enable)
  931                 tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
  932 
  933             if (bp->bpool[i].is_backup)
  934                 tmp |= BMI_EXT_BUF_POOL_BACKUP;
  935 
  936             tmp |= (uint32_t)bp->bpool[i].size;
  937         }
  938 
  939         iowrite32be(tmp, &bp_reg[i]);
  940     }
  941 
  942     /* Clear unused pools */
  943     for (i = bp->count; i < max_bp_num; i++)
  944         iowrite32be(0, &bp_reg[i]);
  945 
  946     /* Pools depletion */
  947     tmp = 0;
  948     for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
  949         if (bp->bpool[i].grp_bp_depleted) {
  950             grp_depl_used = TRUE;
  951             tmp |= 0x80000000 >> i;
  952         }
  953 
  954         if (bp->bpool[i].single_bp_depleted)
  955             tmp |= 0x80 >> i;
  956 
  957         if (bp->bpool[i].pfc_priorities_en)
  958             tmp |= 0x0100 << i;
  959     }
  960 
  961     if (grp_depl_used)
  962         tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) <<
  963             BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
  964 
  965     iowrite32be(tmp, bp_depl_reg);
  966     return 0;
  967 }
  968 
  969 int fman_port_set_rate_limiter(struct fman_port *port,
  970         struct fman_port_rate_limiter *rate_limiter)
  971 {
  972     uint32_t *rate_limit_reg, *rate_limit_scale_reg;
  973     uint32_t granularity, tmp;
  974     uint8_t usec_bit, factor;
  975 
  976     switch (port->type) {
  977     case E_FMAN_PORT_TYPE_TX:
  978     case E_FMAN_PORT_TYPE_TX_10G:
  979         rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt;
  980         rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
  981         granularity = BMI_RATE_LIMIT_GRAN_TX;
  982         break;
  983     case E_FMAN_PORT_TYPE_OP:
  984         rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt;
  985         rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
  986         granularity = BMI_RATE_LIMIT_GRAN_OP;
  987         break;
  988     default:
  989         return -EINVAL;
  990     }
  991 
  992     /* Factor is per 1 usec count */
  993     factor = 1;
  994     usec_bit = rate_limiter->count_1micro_bit;
  995 
  996     /* If rate limit is too small for an 1usec factor, adjust timestamp
  997      * scale and multiply the factor */
  998     while (rate_limiter->rate < (granularity / factor)) {
  999         if (usec_bit == 31)
 1000             /* Can't configure rate limiter - rate is too small */
 1001             return -EINVAL;
 1002 
 1003         usec_bit++;
 1004         factor <<= 1;
 1005     }
 1006 
 1007     /* Figure out register value. The "while" above quarantees that
 1008      * (rate_limiter->rate * factor / granularity) >= 1 */
 1009     tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1);
 1010 
 1011     /* Check rate limit isn't too large */
 1012     if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS)
 1013         return -EINVAL;
 1014 
 1015     /* Check burst size is in allowed range */
 1016     if ((rate_limiter->burst_size == 0) ||
 1017             (rate_limiter->burst_size >
 1018                 BMI_RATE_LIMIT_MAX_BURST_SIZE))
 1019         return -EINVAL;
 1020 
 1021     tmp |= (uint32_t)(rate_limiter->burst_size - 1) <<
 1022             BMI_RATE_LIMIT_MAX_BURST_SHIFT;
 1023 
 1024     if ((port->type == E_FMAN_PORT_TYPE_OP) &&
 1025             (port->fm_rev_maj == 4)) {
 1026         if (rate_limiter->high_burst_size_gran)
 1027             tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN;
 1028     }
 1029 
 1030     iowrite32be(tmp, rate_limit_reg);
 1031 
 1032     /* Set up rate limiter scale register */
 1033     tmp = BMI_RATE_LIMIT_SCALE_EN;
 1034     tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT;
 1035 
 1036     if ((port->type == E_FMAN_PORT_TYPE_OP) &&
 1037             (port->fm_rev_maj == 4))
 1038         tmp |= rate_limiter->rate_factor;
 1039 
 1040     iowrite32be(tmp, rate_limit_scale_reg);
 1041 
 1042     return 0;
 1043 }
 1044 
 1045 int fman_port_delete_rate_limiter(struct fman_port *port)
 1046 {
 1047     uint32_t *rate_limit_scale_reg;
 1048 
 1049     switch (port->type) {
 1050     case E_FMAN_PORT_TYPE_TX:
 1051     case E_FMAN_PORT_TYPE_TX_10G:
 1052         rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
 1053         break;
 1054     case E_FMAN_PORT_TYPE_OP:
 1055         rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
 1056         break;
 1057     default:
 1058         return -EINVAL;
 1059     }
 1060 
 1061     iowrite32be(0, rate_limit_scale_reg);
 1062     return 0;
 1063 }
 1064 
 1065 int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask)
 1066 {
 1067     uint32_t *err_mask_reg;
 1068 
 1069     /* Obtain register address */
 1070     switch (port->type) {
 1071     case E_FMAN_PORT_TYPE_RX:
 1072     case E_FMAN_PORT_TYPE_RX_10G:
 1073         err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem;
 1074         break;
 1075     case E_FMAN_PORT_TYPE_OP:
 1076         err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem;
 1077         break;
 1078     default:
 1079         return -EINVAL;
 1080     }
 1081 
 1082     iowrite32be(err_mask, err_mask_reg);
 1083     return 0;
 1084 }
 1085 
 1086 int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask)
 1087 {
 1088     uint32_t *discard_mask_reg;
 1089 
 1090     /* Obtain register address */
 1091     switch (port->type) {
 1092     case E_FMAN_PORT_TYPE_RX:
 1093     case E_FMAN_PORT_TYPE_RX_10G:
 1094         discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm;
 1095         break;
 1096     case E_FMAN_PORT_TYPE_OP:
 1097         discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm;
 1098         break;
 1099     default:
 1100         return -EINVAL;
 1101     }
 1102 
 1103     iowrite32be(discard_mask, discard_mask_reg);
 1104     return 0;
 1105 }
 1106 
 1107 int fman_port_modify_rx_fd_bits(struct fman_port *port,
 1108         uint8_t rx_fd_bits,
 1109         bool add)
 1110 {
 1111     uint32_t    tmp;
 1112 
 1113     switch (port->type) {
 1114     case E_FMAN_PORT_TYPE_RX:
 1115     case E_FMAN_PORT_TYPE_RX_10G:
 1116         break;
 1117     default:
 1118         return -EINVAL;
 1119     }
 1120 
 1121     tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne);
 1122 
 1123     if (add)
 1124         tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
 1125     else
 1126         tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT);
 1127 
 1128     iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne);
 1129     return 0;
 1130 }
 1131 
 1132 int fman_port_set_perf_cnt_params(struct fman_port *port,
 1133         struct fman_port_perf_cnt_params *params)
 1134 {
 1135     uint32_t *pcp_reg, tmp;
 1136 
 1137     /* Obtain register address and check parameters are in range */
 1138     switch (port->type) {
 1139     case E_FMAN_PORT_TYPE_RX:
 1140     case E_FMAN_PORT_TYPE_RX_10G:
 1141         pcp_reg = &port->bmi_regs->rx.fmbm_rpcp;
 1142         if ((params->queue_val == 0) ||
 1143             (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP))
 1144             return -EINVAL;
 1145         break;
 1146     case E_FMAN_PORT_TYPE_TX:
 1147     case E_FMAN_PORT_TYPE_TX_10G:
 1148         pcp_reg = &port->bmi_regs->tx.fmbm_tpcp;
 1149         if ((params->queue_val == 0) ||
 1150             (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP))
 1151             return -EINVAL;
 1152         break;
 1153     case E_FMAN_PORT_TYPE_OP:
 1154     case E_FMAN_PORT_TYPE_HC:
 1155         pcp_reg = &port->bmi_regs->oh.fmbm_opcp;
 1156         if (params->queue_val != 0)
 1157             return -EINVAL;
 1158         break;
 1159     default:
 1160         return -EINVAL;
 1161     }
 1162 
 1163     if ((params->task_val == 0) ||
 1164             (params->task_val > MAX_PERFORMANCE_TASK_COMP))
 1165         return -EINVAL;
 1166     if ((params->dma_val == 0) ||
 1167             (params->dma_val > MAX_PERFORMANCE_DMA_COMP))
 1168         return -EINVAL;
 1169     if ((params->fifo_val == 0) ||
 1170             ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) >
 1171                 MAX_PERFORMANCE_FIFO_COMP))
 1172         return -EINVAL;
 1173     tmp = (uint32_t)(params->task_val - 1) <<
 1174             BMI_PERFORMANCE_TASK_COMP_SHIFT;
 1175     tmp |= (uint32_t)(params->dma_val - 1) <<
 1176             BMI_PERFORMANCE_DMA_COMP_SHIFT;
 1177     tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1);
 1178 
 1179     switch (port->type) {
 1180     case E_FMAN_PORT_TYPE_RX:
 1181     case E_FMAN_PORT_TYPE_RX_10G:
 1182     case E_FMAN_PORT_TYPE_TX:
 1183     case E_FMAN_PORT_TYPE_TX_10G:
 1184         tmp |= (uint32_t)(params->queue_val - 1) <<
 1185             BMI_PERFORMANCE_QUEUE_COMP_SHIFT;
 1186         break;
 1187     default:
 1188         break;
 1189     }
 1190 
 1191 
 1192     iowrite32be(tmp, pcp_reg);
 1193     return 0;
 1194 }
 1195 
 1196 int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable)
 1197 {
 1198     uint32_t *stats_reg, tmp;
 1199 
 1200     switch (port->type) {
 1201     case E_FMAN_PORT_TYPE_RX:
 1202     case E_FMAN_PORT_TYPE_RX_10G:
 1203         stats_reg = &port->bmi_regs->rx.fmbm_rstc;
 1204         break;
 1205     case E_FMAN_PORT_TYPE_TX:
 1206     case E_FMAN_PORT_TYPE_TX_10G:
 1207         stats_reg = &port->bmi_regs->tx.fmbm_tstc;
 1208         break;
 1209     case E_FMAN_PORT_TYPE_OP:
 1210     case E_FMAN_PORT_TYPE_HC:
 1211         stats_reg = &port->bmi_regs->oh.fmbm_ostc;
 1212         break;
 1213     default:
 1214         return -EINVAL;
 1215     }
 1216 
 1217     tmp = ioread32be(stats_reg);
 1218 
 1219     if (enable)
 1220         tmp |= BMI_COUNTERS_EN;
 1221     else
 1222         tmp &= ~BMI_COUNTERS_EN;
 1223 
 1224     iowrite32be(tmp, stats_reg);
 1225     return 0;
 1226 }
 1227 
 1228 int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable)
 1229 {
 1230     uint32_t *stats_reg, tmp;
 1231 
 1232     switch (port->type) {
 1233     case E_FMAN_PORT_TYPE_RX:
 1234     case E_FMAN_PORT_TYPE_RX_10G:
 1235         stats_reg = &port->bmi_regs->rx.fmbm_rpc;
 1236         break;
 1237     case E_FMAN_PORT_TYPE_TX:
 1238     case E_FMAN_PORT_TYPE_TX_10G:
 1239         stats_reg = &port->bmi_regs->tx.fmbm_tpc;
 1240         break;
 1241     case E_FMAN_PORT_TYPE_OP:
 1242     case E_FMAN_PORT_TYPE_HC:
 1243         stats_reg = &port->bmi_regs->oh.fmbm_opc;
 1244         break;
 1245     default:
 1246         return -EINVAL;
 1247     }
 1248 
 1249     tmp = ioread32be(stats_reg);
 1250 
 1251     if (enable)
 1252         tmp |= BMI_COUNTERS_EN;
 1253     else
 1254         tmp &= ~BMI_COUNTERS_EN;
 1255 
 1256     iowrite32be(tmp, stats_reg);
 1257     return 0;
 1258 }
 1259 
 1260 int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable)
 1261 {
 1262     uint32_t tmp;
 1263 
 1264     tmp = ioread32be(&port->qmi_regs->fmqm_pnc);
 1265 
 1266     if (enable)
 1267         tmp |= QMI_PORT_CFG_EN_COUNTERS;
 1268     else
 1269         tmp &= ~QMI_PORT_CFG_EN_COUNTERS;
 1270 
 1271     iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
 1272     return 0;
 1273 }
 1274 
 1275 int fman_port_set_bpool_cnt_mode(struct fman_port *port,
 1276         uint8_t bpid,
 1277         bool enable)
 1278 {
 1279     uint8_t index;
 1280     uint32_t tmp;
 1281 
 1282     switch (port->type) {
 1283     case E_FMAN_PORT_TYPE_RX:
 1284     case E_FMAN_PORT_TYPE_RX_10G:
 1285         break;
 1286     default:
 1287         return -EINVAL;
 1288     }
 1289 
 1290     /* Find the pool */
 1291     index = fman_port_find_bpool(port, bpid);
 1292     if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
 1293         /* Not found */
 1294         return -EINVAL;
 1295 
 1296     tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]);
 1297 
 1298     if (enable)
 1299         tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
 1300     else
 1301         tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
 1302 
 1303     iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]);
 1304     return 0;
 1305 }
 1306 
 1307 uint32_t fman_port_get_stats_counter(struct fman_port *port,
 1308         enum fman_port_stats_counters  counter)
 1309 {
 1310     uint32_t *stats_reg, ret_val;
 1311 
 1312     switch (port->type) {
 1313     case E_FMAN_PORT_TYPE_RX:
 1314     case E_FMAN_PORT_TYPE_RX_10G:
 1315         get_rx_stats_reg(port, counter, &stats_reg);
 1316         break;
 1317     case E_FMAN_PORT_TYPE_TX:
 1318     case E_FMAN_PORT_TYPE_TX_10G:
 1319         get_tx_stats_reg(port, counter, &stats_reg);
 1320         break;
 1321     case E_FMAN_PORT_TYPE_OP:
 1322     case E_FMAN_PORT_TYPE_HC:
 1323         get_oh_stats_reg(port, counter, &stats_reg);
 1324         break;
 1325     default:
 1326         stats_reg = NULL;
 1327     }
 1328 
 1329     if (stats_reg == NULL)
 1330         return 0;
 1331 
 1332     ret_val = ioread32be(stats_reg);
 1333     return ret_val;
 1334 }
 1335 
 1336 void fman_port_set_stats_counter(struct fman_port *port,
 1337         enum fman_port_stats_counters counter,
 1338         uint32_t value)
 1339 {
 1340     uint32_t *stats_reg;
 1341 
 1342     switch (port->type) {
 1343     case E_FMAN_PORT_TYPE_RX:
 1344     case E_FMAN_PORT_TYPE_RX_10G:
 1345         get_rx_stats_reg(port, counter, &stats_reg);
 1346         break;
 1347     case E_FMAN_PORT_TYPE_TX:
 1348     case E_FMAN_PORT_TYPE_TX_10G:
 1349         get_tx_stats_reg(port, counter, &stats_reg);
 1350         break;
 1351     case E_FMAN_PORT_TYPE_OP:
 1352     case E_FMAN_PORT_TYPE_HC:
 1353         get_oh_stats_reg(port, counter, &stats_reg);
 1354         break;
 1355     default:
 1356         stats_reg = NULL;
 1357     }
 1358 
 1359     if (stats_reg == NULL)
 1360         return;
 1361 
 1362     iowrite32be(value, stats_reg);
 1363 }
 1364 
 1365 uint32_t fman_port_get_perf_counter(struct fman_port *port,
 1366         enum fman_port_perf_counters counter)
 1367 {
 1368     uint32_t *perf_reg, ret_val;
 1369 
 1370     switch (port->type) {
 1371     case E_FMAN_PORT_TYPE_RX:
 1372     case E_FMAN_PORT_TYPE_RX_10G:
 1373         get_rx_perf_reg(port, counter, &perf_reg);
 1374         break;
 1375     case E_FMAN_PORT_TYPE_TX:
 1376     case E_FMAN_PORT_TYPE_TX_10G:
 1377         get_tx_perf_reg(port, counter, &perf_reg);
 1378         break;
 1379     case E_FMAN_PORT_TYPE_OP:
 1380     case E_FMAN_PORT_TYPE_HC:
 1381         get_oh_perf_reg(port, counter, &perf_reg);
 1382         break;
 1383     default:
 1384         perf_reg = NULL;
 1385     }
 1386 
 1387     if (perf_reg == NULL)
 1388         return 0;
 1389 
 1390     ret_val = ioread32be(perf_reg);
 1391     return ret_val;
 1392 }
 1393 
 1394 void fman_port_set_perf_counter(struct fman_port *port,
 1395         enum fman_port_perf_counters counter,
 1396         uint32_t value)
 1397 {
 1398     uint32_t *perf_reg;
 1399 
 1400     switch (port->type) {
 1401     case E_FMAN_PORT_TYPE_RX:
 1402     case E_FMAN_PORT_TYPE_RX_10G:
 1403         get_rx_perf_reg(port, counter, &perf_reg);
 1404         break;
 1405     case E_FMAN_PORT_TYPE_TX:
 1406     case E_FMAN_PORT_TYPE_TX_10G:
 1407         get_tx_perf_reg(port, counter, &perf_reg);
 1408         break;
 1409     case E_FMAN_PORT_TYPE_OP:
 1410     case E_FMAN_PORT_TYPE_HC:
 1411         get_oh_perf_reg(port, counter, &perf_reg);
 1412         break;
 1413     default:
 1414         perf_reg = NULL;
 1415     }
 1416 
 1417     if (perf_reg == NULL)
 1418         return;
 1419 
 1420     iowrite32be(value, perf_reg);
 1421 }
 1422 
 1423 uint32_t fman_port_get_qmi_counter(struct fman_port *port,
 1424         enum fman_port_qmi_counters  counter)
 1425 {
 1426     uint32_t *queue_reg, ret_val;
 1427 
 1428     get_qmi_counter_reg(port, counter, &queue_reg);
 1429 
 1430     if (queue_reg == NULL)
 1431         return 0;
 1432 
 1433     ret_val = ioread32be(queue_reg);
 1434     return ret_val;
 1435 }
 1436 
 1437 void fman_port_set_qmi_counter(struct fman_port *port,
 1438         enum fman_port_qmi_counters counter,
 1439         uint32_t value)
 1440 {
 1441     uint32_t *queue_reg;
 1442 
 1443     get_qmi_counter_reg(port, counter, &queue_reg);
 1444 
 1445     if (queue_reg == NULL)
 1446         return;
 1447 
 1448     iowrite32be(value, queue_reg);
 1449 }
 1450 
 1451 uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid)
 1452 {
 1453     uint8_t index;
 1454     uint32_t ret_val;
 1455 
 1456     switch (port->type) {
 1457     case E_FMAN_PORT_TYPE_RX:
 1458     case E_FMAN_PORT_TYPE_RX_10G:
 1459         break;
 1460     default:
 1461         return 0;
 1462     }
 1463 
 1464     /* Find the pool */
 1465     index = fman_port_find_bpool(port, bpid);
 1466     if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
 1467         /* Not found */
 1468         return 0;
 1469 
 1470     ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]);
 1471     return ret_val;
 1472 }
 1473 
 1474 void fman_port_set_bpool_counter(struct fman_port *port,
 1475         uint8_t bpid,
 1476         uint32_t value)
 1477 {
 1478     uint8_t index;
 1479 
 1480     switch (port->type) {
 1481     case E_FMAN_PORT_TYPE_RX:
 1482     case E_FMAN_PORT_TYPE_RX_10G:
 1483         break;
 1484     default:
 1485         return;
 1486     }
 1487 
 1488     /* Find the pool */
 1489     index = fman_port_find_bpool(port, bpid);
 1490     if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
 1491         /* Not found */
 1492         return;
 1493 
 1494     iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]);
 1495 }
 1496 
 1497 int fman_port_add_congestion_grps(struct fman_port *port,
 1498         uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
 1499 {
 1500     int i;
 1501     uint32_t tmp, *grp_map_reg;
 1502     uint8_t max_grp_map_num;
 1503 
 1504     switch (port->type) {
 1505     case E_FMAN_PORT_TYPE_RX:
 1506     case E_FMAN_PORT_TYPE_RX_10G:
 1507         if (port->fm_rev_maj == 4)
 1508             max_grp_map_num = 1;
 1509         else
 1510             max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
 1511         grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
 1512         break;
 1513     case E_FMAN_PORT_TYPE_OP:
 1514         max_grp_map_num = 1;
 1515         if (port->fm_rev_maj != 4)
 1516             return -EINVAL;
 1517         grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
 1518         break;
 1519     default:
 1520         return -EINVAL;
 1521     }
 1522 
 1523     for (i = (max_grp_map_num - 1); i >= 0; i--) {
 1524         if (grps_map[i] == 0)
 1525             continue;
 1526         tmp = ioread32be(&grp_map_reg[i]);
 1527         tmp |= grps_map[i];
 1528         iowrite32be(tmp, &grp_map_reg[i]);
 1529     }
 1530 
 1531     return 0;
 1532 }
 1533 
 1534 int fman_port_remove_congestion_grps(struct fman_port *port,
 1535         uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
 1536 {
 1537     int i;
 1538     uint32_t tmp, *grp_map_reg;
 1539     uint8_t max_grp_map_num;
 1540 
 1541     switch (port->type) {
 1542     case E_FMAN_PORT_TYPE_RX:
 1543     case E_FMAN_PORT_TYPE_RX_10G:
 1544         if (port->fm_rev_maj == 4)
 1545             max_grp_map_num = 1;
 1546         else
 1547             max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
 1548         grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
 1549         break;
 1550     case E_FMAN_PORT_TYPE_OP:
 1551         max_grp_map_num = 1;
 1552         if (port->fm_rev_maj != 4)
 1553             return -EINVAL;
 1554         grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
 1555         break;
 1556     default:
 1557         return -EINVAL;
 1558     }
 1559 
 1560     for (i = (max_grp_map_num - 1); i >= 0; i--) {
 1561         if (grps_map[i] == 0)
 1562             continue;
 1563         tmp = ioread32be(&grp_map_reg[i]);
 1564         tmp &= ~grps_map[i];
 1565         iowrite32be(tmp, &grp_map_reg[i]);
 1566     }
 1567     return 0;
 1568 }

Cache object: 7f42c2c396853e4b68ff0c55afc2d4fe


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