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/Pcd/fman_kg.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 #include "fsl_fman_kg.h"
   34 
   35 /****************************************/
   36 /*       static functions               */
   37 /****************************************/
   38 
   39 
   40 static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write)
   41 {
   42         uint32_t rw;
   43 
   44         rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
   45 
   46         return (uint32_t)(FM_KG_KGAR_GO |
   47                         rw |
   48                         FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
   49                         hwport_id |
   50                         FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
   51 }
   52 
   53 static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id)
   54 {
   55         uint32_t ar;
   56 
   57         fman_kg_write_sp(regs, 0xffffffff, 0);
   58 
   59         ar = build_ar_bind_scheme(hwport_id, TRUE);
   60         fman_kg_write_ar_wait(regs, ar);
   61 }
   62 
   63 static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write)
   64 {
   65         uint32_t rw;
   66 
   67         rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
   68 
   69         return (uint32_t)(FM_KG_KGAR_GO |
   70                         rw |
   71                         FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
   72                         hwport_id |
   73                         FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
   74 }
   75 
   76 static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id)
   77 {
   78         uint32_t ar;
   79 
   80         fman_kg_write_cpp(regs, 0);
   81 
   82         ar = build_ar_bind_cls_plan(hwport_id, TRUE);
   83         fman_kg_write_ar_wait(regs, ar);
   84 }
   85 
   86 static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src,
   87                                 bool no_validation,
   88                                 uint8_t *offset)
   89 {
   90         int     code;
   91 
   92         switch (src) {
   93         case E_FMAN_KG_GEN_EXTRACT_ETH:
   94                 code = no_validation ? 0x73 : 0x3;
   95                 break;
   96 
   97         case E_FMAN_KG_GEN_EXTRACT_ETYPE:
   98                 code = no_validation ? 0x77 : 0x7;
   99                 break;
  100  
  101         case E_FMAN_KG_GEN_EXTRACT_SNAP:
  102                 code = no_validation ? 0x74 : 0x4;
  103                 break;
  104 
  105         case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1:
  106                 code = no_validation ? 0x75 : 0x5;
  107                 break;
  108 
  109         case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N:
  110                 code = no_validation ? 0x76 : 0x6;
  111                 break;
  112 
  113         case E_FMAN_KG_GEN_EXTRACT_PPPoE:
  114                 code = no_validation ? 0x78 : 0x8;
  115                 break;
  116 
  117         case E_FMAN_KG_GEN_EXTRACT_MPLS_1:
  118                 code = no_validation ? 0x79 : 0x9;
  119                 break;
  120 
  121         case E_FMAN_KG_GEN_EXTRACT_MPLS_2:
  122                 code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19;
  123                 break;
  124 
  125         case E_FMAN_KG_GEN_EXTRACT_MPLS_3:
  126                 code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29;
  127                 break;
  128 
  129         case E_FMAN_KG_GEN_EXTRACT_MPLS_N:
  130                 code = no_validation ? 0x7a : 0xa;
  131                 break;
  132 
  133         case E_FMAN_KG_GEN_EXTRACT_IPv4_1:
  134                 code = no_validation ? 0x7b : 0xb;
  135                 break;
  136 
  137         case E_FMAN_KG_GEN_EXTRACT_IPv6_1:
  138                 code = no_validation ? 0x7b : 0x1b;
  139                 break;
  140 
  141         case E_FMAN_KG_GEN_EXTRACT_IPv4_2:
  142                 code = no_validation ? 0x7c : 0xc;
  143                 break;
  144 
  145         case E_FMAN_KG_GEN_EXTRACT_IPv6_2:
  146                 code = no_validation ? 0x7c : 0x1c;
  147                 break;
  148 
  149         case E_FMAN_KG_GEN_EXTRACT_MINENCAP:
  150                 code = no_validation ? 0x7c : 0x2c;
  151                 break;
  152 
  153         case E_FMAN_KG_GEN_EXTRACT_IP_PID:
  154                 code = no_validation ? 0x72 : 0x2;
  155                 break;
  156 
  157         case E_FMAN_KG_GEN_EXTRACT_GRE:
  158                 code = no_validation ? 0x7d : 0xd;
  159                 break;
  160 
  161         case E_FMAN_KG_GEN_EXTRACT_TCP:
  162                 code = no_validation ? 0x7e : 0xe;
  163                 break;
  164 
  165         case E_FMAN_KG_GEN_EXTRACT_UDP:
  166                 code = no_validation ? 0x7e : 0x1e;
  167                 break;
  168 
  169         case E_FMAN_KG_GEN_EXTRACT_SCTP:
  170                 code = no_validation ? 0x7e : 0x3e;
  171                 break;
  172 
  173         case E_FMAN_KG_GEN_EXTRACT_DCCP:
  174                 code = no_validation ? 0x7e : 0x4e;
  175                 break;
  176 
  177         case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH:
  178                 code = no_validation ? 0x7e : 0x2e;
  179                 break;
  180 
  181         case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP:
  182                 code = no_validation ? 0x7e : 0x6e;
  183                 break;
  184 
  185         case E_FMAN_KG_GEN_EXTRACT_SHIM_1:
  186                 code = 0x70;
  187                 break;
  188 
  189         case E_FMAN_KG_GEN_EXTRACT_SHIM_2:
  190                 code = 0x71;
  191                 break;
  192 
  193         case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT:
  194                 code = 0x10;
  195                 break;
  196 
  197         case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START:
  198                 code = 0x40;
  199                 break;
  200 
  201         case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT:
  202                 code = 0x20;
  203                 break;
  204 
  205         case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE:
  206                 code = 0x7f;
  207                 break;
  208 
  209         case E_FMAN_KG_GEN_EXTRACT_FROM_FQID:
  210                 code = 0x20;
  211                 *offset += 0x20;
  212                 break;
  213 
  214         default:
  215                 code = FM_KG_SCH_GEN_HT_INVALID;
  216         }
  217 
  218         return (uint8_t)code;
  219 }
  220 
  221 static uint32_t build_ar_scheme(uint8_t scheme,
  222                                 uint8_t hwport_id,
  223                                 bool update_counter,
  224                                 bool write)
  225 {
  226         uint32_t rw;
  227 
  228         rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
  229 
  230         return (uint32_t)(FM_KG_KGAR_GO |
  231                         rw |
  232                         FM_KG_KGAR_SEL_SCHEME_ENTRY |
  233                         hwport_id |
  234                         ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) |
  235                         (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
  236 }
  237 
  238 static uint32_t build_ar_cls_plan(uint8_t grp,
  239                                         uint8_t entries_mask,
  240                                         uint8_t hwport_id,
  241                                         bool write)
  242 {
  243         uint32_t rw;
  244 
  245         rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
  246 
  247         return (uint32_t)(FM_KG_KGAR_GO |
  248                         rw |
  249                         FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
  250                         hwport_id |
  251                         ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) |
  252                         ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT));
  253 }
  254 
  255 int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar)
  256 {
  257         iowrite32be(fmkg_ar, &regs->fmkg_ar);
  258         /* Wait for GO to be idle and read error */
  259         while ((fmkg_ar = ioread32be(&regs->fmkg_ar)) & FM_KG_KGAR_GO) ;
  260         if (fmkg_ar & FM_PCD_KG_KGAR_ERR)
  261                 return -EINVAL;
  262         return 0;
  263 }
  264 
  265 void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add)
  266 {
  267 
  268         struct fman_kg_pe_regs *kgpe_regs;
  269         uint32_t tmp;
  270 
  271         kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
  272         tmp = ioread32be(&kgpe_regs->fmkg_pe_sp);
  273 
  274         if (add)
  275                 tmp |= sp;
  276         else /* clear */
  277                 tmp &= ~sp;
  278 
  279         iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp);
  280 
  281 }
  282 
  283 void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp)
  284 {
  285         struct fman_kg_pe_regs *kgpe_regs;
  286 
  287         kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
  288 
  289         iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp);
  290 }
  291 
  292 void fman_kg_get_event(struct fman_kg_regs *regs,
  293                         uint32_t *event,
  294                         uint32_t *scheme_idx)
  295 {
  296         uint32_t mask, force;
  297 
  298         *event = ioread32be(&regs->fmkg_eer);
  299         mask = ioread32be(&regs->fmkg_eeer);
  300         *scheme_idx = ioread32be(&regs->fmkg_seer);
  301         *scheme_idx &= ioread32be(&regs->fmkg_seeer);
  302 
  303         *event &= mask;
  304 
  305         /* clear the forced events */
  306         force = ioread32be(&regs->fmkg_feer);
  307         if (force & *event)
  308                 iowrite32be(force & ~*event ,&regs->fmkg_feer);
  309 
  310         iowrite32be(*event, &regs->fmkg_eer);
  311         iowrite32be(*scheme_idx, &regs->fmkg_seer);
  312 }
  313 
  314 
  315 void fman_kg_init(struct fman_kg_regs *regs,
  316                         uint32_t exceptions,
  317                         uint32_t dflt_nia)
  318 {
  319         uint32_t tmp;
  320         int i;
  321 
  322         iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
  323                         &regs->fmkg_eer);
  324 
  325         tmp = 0;
  326         if (exceptions & FM_EX_KG_DOUBLE_ECC)
  327                 tmp |= FM_EX_KG_DOUBLE_ECC;
  328 
  329         if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)
  330                 tmp |= FM_EX_KG_KEYSIZE_OVERFLOW;
  331 
  332         iowrite32be(tmp, &regs->fmkg_eeer);
  333         iowrite32be(0, &regs->fmkg_fdor);
  334         iowrite32be(0, &regs->fmkg_gdv0r);
  335         iowrite32be(0, &regs->fmkg_gdv1r);
  336         iowrite32be(dflt_nia, &regs->fmkg_gcr);
  337 
  338         /* Clear binding between ports to schemes and classification plans
  339          * so that all ports are not bound to any scheme/classification plan */
  340         for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
  341                 clear_pe_all_scheme(regs, (uint8_t)i);
  342                 clear_pe_all_cls_plan(regs, (uint8_t)i);
  343         }
  344 }
  345 
  346 void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs)
  347 {
  348         /* enable and enable all scheme interrupts */
  349         iowrite32be(0xFFFFFFFF, &regs->fmkg_seer);
  350         iowrite32be(0xFFFFFFFF, &regs->fmkg_seeer);
  351 }
  352 
  353 void fman_kg_enable(struct fman_kg_regs *regs)
  354 {
  355         iowrite32be(ioread32be(&regs->fmkg_gcr) | FM_KG_KGGCR_EN,
  356                         &regs->fmkg_gcr);
  357 }
  358 
  359 void fman_kg_disable(struct fman_kg_regs *regs)
  360 {
  361         iowrite32be(ioread32be(&regs->fmkg_gcr) & ~FM_KG_KGGCR_EN,
  362                         &regs->fmkg_gcr);
  363 }
  364 
  365 void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset)
  366 {
  367         iowrite32be(offset, &regs->fmkg_fdor);
  368 }
  369 
  370 void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
  371                                 uint8_t def_id,
  372                                 uint32_t val)
  373 {
  374         if(def_id == 0)
  375                 iowrite32be(val, &regs->fmkg_gdv0r);
  376         else
  377                 iowrite32be(val, &regs->fmkg_gdv1r);
  378 }
  379 
  380 
  381 void fman_kg_set_exception(struct fman_kg_regs *regs,
  382                                 uint32_t exception,
  383                                 bool enable)
  384 {
  385         uint32_t tmp;
  386 
  387         tmp = ioread32be(&regs->fmkg_eeer);
  388 
  389         if (enable) {
  390                 tmp |= exception;
  391         } else {
  392                 tmp &= ~exception;
  393         }
  394 
  395         iowrite32be(tmp, &regs->fmkg_eeer);
  396 }
  397 
  398 void fman_kg_get_exception(struct fman_kg_regs *regs,
  399                                 uint32_t *events,
  400                                 uint32_t *scheme_ids,
  401                                 bool clear)
  402 {
  403         uint32_t mask;
  404 
  405         *events = ioread32be(&regs->fmkg_eer);
  406         mask = ioread32be(&regs->fmkg_eeer);
  407         *events &= mask;
  408  
  409         *scheme_ids = 0;
  410 
  411         if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) {
  412                 *scheme_ids = ioread32be(&regs->fmkg_seer);
  413                 mask = ioread32be(&regs->fmkg_seeer);
  414                 *scheme_ids &= mask;
  415         }
  416 
  417         if (clear) {
  418                 iowrite32be(*scheme_ids, &regs->fmkg_seer);
  419                 iowrite32be(*events, &regs->fmkg_eer);
  420         }
  421 }
  422 
  423 void fman_kg_get_capture(struct fman_kg_regs *regs,
  424                                 struct fman_kg_ex_ecc_attr *ecc_attr,
  425                                 bool clear)
  426 {
  427         uint32_t tmp;
  428 
  429         tmp = ioread32be(&regs->fmkg_serc);
  430 
  431         if (tmp & KG_FMKG_SERC_CAP) {
  432                 /* Captured data is valid */
  433                 ecc_attr->valid = TRUE;
  434                 ecc_attr->double_ecc =
  435                         (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE);
  436                 ecc_attr->single_ecc_count =
  437                         (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >>
  438                                         KG_FMKG_SERC_CNT_SHIFT);
  439                 ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK);
  440 
  441                 if (clear)
  442                         iowrite32be(KG_FMKG_SERC_CAP, &regs->fmkg_serc);
  443         } else {
  444                 /* No ECC error is captured */
  445                 ecc_attr->valid = FALSE;
  446         }
  447 }
  448 
  449 int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
  450                                 struct fman_kg_scheme_regs *scheme_regs)
  451 {
  452         struct fman_kg_extract_params *extract_params;
  453         struct fman_kg_gen_extract_params *gen_params;
  454         uint32_t tmp_reg, i, select, mask, fqb;
  455         uint8_t offset, shift, ht;
  456 
  457         /* Zero out all registers so no need to care about unused ones */
  458         memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
  459 
  460         /* Mode register */
  461         tmp_reg = fm_kg_build_nia(params->next_engine,
  462                         params->next_engine_action);
  463         if (tmp_reg == KG_NIA_INVALID) {
  464                 return -EINVAL;
  465         }
  466 
  467         if (params->next_engine == E_FMAN_PCD_PLCR) {
  468                 tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR;
  469         }
  470         else if (params->next_engine == E_FMAN_PCD_CC) {
  471                 tmp_reg |= (uint32_t)params->cc_params.base_offset <<
  472                                 FMAN_KG_SCH_MODE_CCOBASE_SHIFT;
  473         }
  474 
  475         tmp_reg |= FMAN_KG_SCH_MODE_EN;
  476         scheme_regs->kgse_mode = tmp_reg;
  477 
  478         /* Match vector */
  479         scheme_regs->kgse_mv = params->match_vector;
  480 
  481         extract_params = &params->extract_params;
  482 
  483         /* Scheme default values registers */
  484         scheme_regs->kgse_dv0 = extract_params->def_scheme_0;
  485         scheme_regs->kgse_dv1 = extract_params->def_scheme_1;
  486 
  487         /* Extract Known Fields Command register */
  488         scheme_regs->kgse_ekfc = extract_params->known_fields;
  489 
  490         /* Entry Extract Known Default Value register */
  491         tmp_reg = 0;
  492         tmp_reg |= extract_params->known_fields_def.mac_addr <<
  493                         FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT;
  494         tmp_reg |= extract_params->known_fields_def.vlan_tci <<
  495                         FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT;
  496         tmp_reg |= extract_params->known_fields_def.etype <<
  497                         FMAN_KG_SCH_DEF_ETYPE_SHIFT;
  498         tmp_reg |= extract_params->known_fields_def.ppp_sid <<
  499                         FMAN_KG_SCH_DEF_PPP_SID_SHIFT;
  500         tmp_reg |= extract_params->known_fields_def.ppp_pid <<
  501                         FMAN_KG_SCH_DEF_PPP_PID_SHIFT;
  502         tmp_reg |= extract_params->known_fields_def.mpls <<
  503                         FMAN_KG_SCH_DEF_MPLS_SHIFT;
  504         tmp_reg |= extract_params->known_fields_def.ip_addr <<
  505                         FMAN_KG_SCH_DEF_IP_ADDR_SHIFT;
  506         tmp_reg |= extract_params->known_fields_def.ptype <<
  507                         FMAN_KG_SCH_DEF_PTYPE_SHIFT;
  508         tmp_reg |= extract_params->known_fields_def.ip_tos_tc <<
  509                         FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT;
  510         tmp_reg |= extract_params->known_fields_def.ipv6_fl <<
  511                         FMAN_KG_SCH_DEF_IPv6_FL_SHIFT;
  512         tmp_reg |= extract_params->known_fields_def.ipsec_spi <<
  513                         FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT;
  514         tmp_reg |= extract_params->known_fields_def.l4_port <<
  515                         FMAN_KG_SCH_DEF_L4_PORT_SHIFT;
  516         tmp_reg |= extract_params->known_fields_def.tcp_flg <<
  517                         FMAN_KG_SCH_DEF_TCP_FLG_SHIFT;
  518 
  519         scheme_regs->kgse_ekdv = tmp_reg;
  520 
  521         /* Generic extract registers */
  522         if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) {
  523                 return -EINVAL;
  524         }
  525 
  526         for (i = 0; i < extract_params->gen_extract_num; i++) {
  527                 gen_params = extract_params->gen_extract + i;
  528 
  529                 tmp_reg = FMAN_KG_SCH_GEN_VALID;
  530                 tmp_reg |= (uint32_t)gen_params->def_val <<
  531                                 FMAN_KG_SCH_GEN_DEF_SHIFT;
  532 
  533                 if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) {
  534                         if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) ||
  535                                         (gen_params->extract == 0)) {
  536                                 return -EINVAL;
  537                         }
  538                 } else {
  539                         tmp_reg |= FMAN_KG_SCH_GEN_OR;
  540                 }
  541 
  542                 tmp_reg |= (uint32_t)gen_params->extract <<
  543                                 FMAN_KG_SCH_GEN_SIZE_SHIFT;
  544                 tmp_reg |= (uint32_t)gen_params->mask <<
  545                                 FMAN_KG_SCH_GEN_MASK_SHIFT;
  546 
  547                 offset = gen_params->offset;
  548                 ht = get_gen_ht_code(gen_params->src,
  549                                 gen_params->no_validation,
  550                                 &offset);
  551                 tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT;
  552                 tmp_reg |= offset;
  553 
  554                 scheme_regs->kgse_gec[i] = tmp_reg;
  555         }
  556 
  557         /* Masks registers */
  558         if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) {
  559                 return -EINVAL;
  560         }
  561 
  562         select = 0;
  563         mask = 0;
  564         fqb = 0;
  565         for (i = 0; i < extract_params->masks_num; i++) {
  566                 /* MCSx fields */
  567                 KG_GET_MASK_SEL_SHIFT(shift, i);
  568                 if (extract_params->masks[i].is_known) {
  569                         /* Mask known field */
  570                         select |= extract_params->masks[i].field_or_gen_idx <<
  571                                         shift;
  572                 } else {
  573                         /* Mask generic extract */
  574                         select |= (extract_params->masks[i].field_or_gen_idx +
  575                                         FM_KG_MASK_SEL_GEN_BASE) << shift;
  576                 }
  577 
  578                 /* MOx fields - spread between se_bmch and se_fqb registers */
  579                 KG_GET_MASK_OFFSET_SHIFT(shift, i);
  580                 if (i < 2) {
  581                         select |= (uint32_t)extract_params->masks[i].offset <<
  582                                         shift;
  583                 } else {
  584                         fqb |= (uint32_t)extract_params->masks[i].offset <<
  585                                         shift;
  586                 }
  587 
  588                 /* BMx fields */
  589                 KG_GET_MASK_SHIFT(shift, i);
  590                 mask |= (uint32_t)extract_params->masks[i].mask << shift;
  591         }
  592 
  593         /* Finish with rest of BMx fileds -
  594          * don't mask bits for unused masks by setting
  595          * corresponding BMx field = 0xFF */
  596         for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) {
  597                 KG_GET_MASK_SHIFT(shift, i);
  598                 mask |= 0xFF << shift;
  599         }
  600 
  601         scheme_regs->kgse_bmch = select;
  602         scheme_regs->kgse_bmcl = mask;
  603 
  604         /* Finish with FQB register initialization.
  605          * Check fqid is 24-bit value. */
  606         if (params->base_fqid & ~0x00FFFFFF) {
  607                 return -EINVAL;
  608         }
  609 
  610         fqb |= params->base_fqid;
  611         scheme_regs->kgse_fqb = fqb;
  612 
  613         /* Hash Configuration register */
  614         tmp_reg = 0;
  615         if (params->hash_params.use_hash) {
  616                 /* Check hash mask is 24-bit value */
  617                 if (params->hash_params.mask & ~0x00FFFFFF) {
  618                         return -EINVAL;
  619                 }
  620 
  621                 /* Hash function produces 64-bit value, 24 bits of that
  622                  * are used to generate fq_id and policer profile.
  623                  * Thus, maximal shift is 40 bits to allow 24 bits out of 64.
  624                  */
  625                 if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) {
  626                         return -EINVAL;
  627                 }
  628 
  629                 tmp_reg |= params->hash_params.mask;
  630                 tmp_reg |= (uint32_t)params->hash_params.shift_r <<
  631                                 FMAN_KG_SCH_HASH_HSHIFT_SHIFT;
  632 
  633                 if (params->hash_params.sym) {
  634                         tmp_reg |= FMAN_KG_SCH_HASH_SYM;
  635                 }
  636 
  637         }
  638 
  639         if (params->bypass_fqid_gen) {
  640                 tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN;
  641         }
  642 
  643         scheme_regs->kgse_hc = tmp_reg;
  644 
  645         /* Policer Profile register */
  646         if (params->policer_params.bypass_pp_gen) {
  647                 tmp_reg = 0;
  648         } else {
  649                 /* Lower 8 bits of 24-bits extracted from hash result
  650                  * are used for policer profile generation.
  651                  * That leaves maximum shift value = 23. */
  652                 if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) {
  653                         return -EINVAL;
  654                 }
  655 
  656                 tmp_reg = params->policer_params.base;
  657                 tmp_reg |= ((uint32_t)params->policer_params.shift <<
  658                                 FMAN_KG_SCH_PP_SH_SHIFT) &
  659                                 FMAN_KG_SCH_PP_SH_MASK;
  660                 tmp_reg |= ((uint32_t)params->policer_params.shift <<
  661                                 FMAN_KG_SCH_PP_SL_SHIFT) &
  662                                 FMAN_KG_SCH_PP_SL_MASK;
  663                 tmp_reg |= (uint32_t)params->policer_params.mask <<
  664                                 FMAN_KG_SCH_PP_MASK_SHIFT;
  665         }
  666 
  667         scheme_regs->kgse_ppc = tmp_reg;
  668 
  669         /* Coarse Classification Bit Select register */
  670         if (params->next_engine == E_FMAN_PCD_CC) {
  671                 scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel;
  672         }
  673 
  674         /* Packets Counter register */
  675         if (params->update_counter) {
  676                 scheme_regs->kgse_spc = params->counter_value;
  677         }
  678 
  679         return 0;
  680 }
  681 
  682 int fman_kg_write_scheme(struct fman_kg_regs *regs,
  683                                 uint8_t scheme_id,
  684                                 uint8_t hwport_id,
  685                                 struct fman_kg_scheme_regs *scheme_regs,
  686                                 bool update_counter)
  687 {
  688         struct fman_kg_scheme_regs *kgse_regs;
  689         uint32_t tmp_reg;
  690         int err, i;
  691 
  692         /* Write indirect scheme registers */
  693         kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
  694 
  695         iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode);
  696         iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc);
  697         iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv);
  698         iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch);
  699         iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl);
  700         iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb);
  701         iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc);
  702         iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc);
  703         iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc);
  704         iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0);
  705         iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1);
  706         iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs);
  707         iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv);
  708 
  709         for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
  710                 iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]);
  711 
  712         /* Write AR (Action register) */
  713         tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE);
  714         err = fman_kg_write_ar_wait(regs, tmp_reg);
  715         return err;
  716 }
  717 
  718 int fman_kg_delete_scheme(struct fman_kg_regs *regs,
  719                                 uint8_t scheme_id,
  720                                 uint8_t hwport_id)
  721 {
  722         struct fman_kg_scheme_regs *kgse_regs;
  723         uint32_t tmp_reg;
  724         int err, i;
  725 
  726         kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
  727 
  728         /* Clear all registers including enable bit in mode register */
  729         for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) {
  730                 iowrite32be(0, ((uint32_t *)kgse_regs + i));
  731         }
  732 
  733         /* Write AR (Action register) */
  734         tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE);
  735         err = fman_kg_write_ar_wait(regs, tmp_reg);
  736         return err;
  737 }
  738 
  739 int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
  740                                 uint8_t scheme_id,
  741                                 uint8_t hwport_id,
  742                                 uint32_t *counter)
  743 {
  744         struct fman_kg_scheme_regs  *kgse_regs;
  745         uint32_t                    tmp_reg;
  746         int                         err;
  747 
  748         kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
  749  
  750         tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
  751         err = fman_kg_write_ar_wait(regs, tmp_reg);
  752 
  753         if (err != 0)
  754                 return err;
  755 
  756         *counter = ioread32be(&kgse_regs->kgse_spc);
  757 
  758         return 0;
  759 }
  760 
  761 int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
  762                                 uint8_t scheme_id,
  763                                 uint8_t hwport_id,
  764                                 uint32_t counter)
  765 {
  766         struct fman_kg_scheme_regs *kgse_regs;
  767         uint32_t tmp_reg;
  768         int err;
  769 
  770         kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
  771 
  772         tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
  773 
  774         err = fman_kg_write_ar_wait(regs, tmp_reg);
  775         if (err != 0)
  776                 return err;
  777  
  778         /* Keygen indirect access memory contains all scheme_id registers
  779          * by now. Change only counter value. */
  780         iowrite32be(counter, &kgse_regs->kgse_spc);
  781 
  782         /* Write back scheme registers */
  783         tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE);
  784         err = fman_kg_write_ar_wait(regs, tmp_reg);
  785 
  786         return err;
  787 }
  788 
  789 uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs)
  790 {
  791     return ioread32be(&regs->fmkg_tpc);
  792 }
  793 
  794 int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
  795                                 struct fman_kg_cp_regs *cls_plan_regs)
  796 {
  797         uint8_t entries_set, entry_bit;
  798         int i;
  799 
  800         /* Zero out all group's register */
  801         memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs));
  802 
  803         /* Go over all classification entries in params->entries_mask and
  804          * configure the corresponding cpe register */
  805         entries_set = params->entries_mask;
  806         for (i = 0; entries_set; i++) {
  807                 entry_bit = (uint8_t)(0x80 >> i);
  808                 if ((entry_bit & entries_set) == 0)
  809                         continue;
  810                 entries_set ^= entry_bit;
  811                 cls_plan_regs->kgcpe[i] = params->mask_vector[i];
  812         }
  813 
  814         return 0;
  815 }
  816 
  817 int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
  818                                 uint8_t grp_id,
  819                                 uint8_t entries_mask,
  820                                 uint8_t hwport_id,
  821                                 struct fman_kg_cp_regs *cls_plan_regs)
  822 {
  823         struct fman_kg_cp_regs *kgcpe_regs;
  824         uint32_t tmp_reg;
  825         int i, err;
  826 
  827         /* Check group index is valid and the group isn't empty */
  828         if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM)
  829                 return -EINVAL;
  830 
  831         /* Write indirect classification plan registers */
  832         kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]);
  833 
  834         for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) {
  835                 iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]);
  836         }
  837 
  838         tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE);
  839         err = fman_kg_write_ar_wait(regs, tmp_reg);
  840         return err;
  841 }
  842 
  843 int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
  844                                 uint8_t hwport_id,
  845                                 uint32_t schemes)
  846 {
  847         struct fman_kg_pe_regs *kg_pe_regs;
  848         uint32_t tmp_reg;
  849         int err;
  850 
  851         kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
  852 
  853         iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp);
  854 
  855         tmp_reg = build_ar_bind_scheme(hwport_id, TRUE);
  856         err = fman_kg_write_ar_wait(regs, tmp_reg);
  857         return err;
  858 }
  859 
  860 int fman_kg_build_bind_cls_plans(uint8_t grp_base,
  861                                         uint8_t grp_mask,
  862                                         uint32_t *bind_cls_plans)
  863 {
  864         /* Check grp_base and grp_mask are 5-bits values */
  865         if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F))
  866                 return -EINVAL;
  867 
  868         *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base);
  869         return 0;
  870 }
  871 
  872 
  873 int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
  874                                         uint8_t hwport_id,
  875                                         uint32_t bind_cls_plans)
  876 {
  877         struct fman_kg_pe_regs *kg_pe_regs;
  878         uint32_t tmp_reg;
  879         int err;
  880 
  881         kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
  882 
  883         iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp);
  884 
  885         tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE);
  886         err = fman_kg_write_ar_wait(regs, tmp_reg);
  887         return err;
  888 }

Cache object: 4e98c7f9d501c02161d9af749a4ee199


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